在C中,编译器将按照声明它们的顺序布置结构的成员,在成员之间插入可能的填充字节,或者在最后一个成员之后插入,以确保每个成员正确对齐.
gcc提供了一种语言扩展,__attribute__((packed))它告诉编译器不要插入填充,允许结构成员不对齐.例如,如果系统通常要求所有int对象都具有4字节对齐,则__attribute__((packed))可能导致int在奇数偏移处分配struct成员.
引用gcc文档:
`packed'属性指定变量或结构字段应该具有尽可能小的对齐 - 变量的一个字节和字段的一个位,除非您使用`aligned'属性指定更大的值.
显然,使用此扩展可以导致更小的数据要求但代码更慢,因为编译器必须(在某些平台上)生成代码,以便一次一个字节地访问未对齐的成员.
但有任何不安全的情况吗?编译器是否始终生成正确(但速度较慢)的代码来访问打包结构的未对齐成员?在所有情况下都可以这样做吗?
为什么第一种情况下不是12?测试:最新版本的gcc和clang,64位Linux
struct desc
{
int** parts;
int nr;
};
Run Code Online (Sandbox Code Playgroud)
sizeof(desc); Output: 16
struct desc
{
int** parts;
};
Run Code Online (Sandbox Code Playgroud)
sizeof(desc); Output: 8
struct desc
{
int nr;
};
Run Code Online (Sandbox Code Playgroud)
sizeof(desc); Output: 4
可能重复:
如何找到结构的大小?
结构的内存大小不同?
我使用以下结构进行网络通信,它在中间创建了许多不必要的字节.
它提供的大小与预期的8字节不同.
struct HttpPacket {
unsigned char x1;
union {
struct {
unsigned char len;
unsigned short host;
unsigned char content[4];
} packet;
unsigned char bytes[7];
unsigned long num;
}
Run Code Online (Sandbox Code Playgroud)
并且以下给出了不同的大小,即使我从联合中删除了一个字段
struct HttpPacket {
unsigned char x1;
union {
struct {
unsigned char len;
unsigned short host;
unsigned char content[4];
} packet;
unsigned long num;
}
Run Code Online (Sandbox Code Playgroud)
另外,一个更明显的例子
struct {
unsigned char len;
unsigned short host;
unsigned char content[4];
} packet;
Run Code Online (Sandbox Code Playgroud)
它的大小为8,而不是7.我再添加一个字段,它仍然给出相同的大小
struct {
unsigned char EXTRAADDEDFIELD;
unsigned …Run Code Online (Sandbox Code Playgroud)