包含packed结构体的容器结构体是否会被编译器保证为packed?
答案:没有明确的保证
简单来说:即使容器的所有成员都是被声明为__attribute__((packed))的压缩结构体,容器本身也不会自动被视为压缩结构体,编译器完全可能在成员之间插入内存填充。
原因可以拆解为这几点:
__attribute__((packed))的作用范围是单个结构体本身:它仅保证被标记的结构体内部不会因为对齐需求插入填充,但不会改变包含它的父结构体的布局规则。父结构体的成员布局仍然遵循编译器默认的对齐策略。- 举个具体的例子:假设
Packed1是一个packed的结构体,大小为3字节(比如包含三个char字段),Packed2是一个packed的结构体,内部包含一个int(4字节)。编译器为了让Packed2的起始地址满足4字节对齐要求,会在first和second之间插入1字节的填充——这时候容器结构体就存在内存空洞了,即便两个成员本身都是无填充的。
如果想要确保容器结构体也是无填充的,你必须显式地给容器结构体本身加上__attribute__((packed))属性,比如:
struct ContainerOfPacked __attribute__((packed)) { Packed1 first; // 本身是packed结构体 Packed2 second; // 本身是packed结构体 };
只有这样,编译器才会保证容器内部的成员之间没有填充,整体是压缩的。
需要注意的是,虽然主流编译器(GCC、Clang等)的行为基本一致,但__attribute__((packed))本身是GNU扩展,不属于C标准,所以具体细节可能因编译器而异,但核心规则是统一的:成员的packed属性不会自动传递给容器结构体。
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

