【发布时间】:2016-12-11 19:18:27
【问题描述】:
struct A
{
uint32_t var1;
uint32_t var2;
uint32_t var3;
uint32_t var4;
uint32_t var5;
};
在上述结构中,编译器不填充并分配 20 个字节。
现在我们有了另一个结构,它包含一个 8 字节变量而不是两个 4 字节。在这种情况下,编译器填充并分配 24 个字节给这个结构。
struct B
{
uint32_t var1;
uint32_t var2;
uint32_t var3;
uint64_t var5;
};
为什么会有这样的行为? 如果编译器将数据对齐到 8 字节边界,那么第一个结构中应该有 4 个字节的填充,并且应该 在这种情况下不要填充第二个结构。并且如果编译器将数据对齐到 4 字节边界,那么为什么在第二个结构中有 4 字节的填充?
编译器:GCC 平台:64位linux,x86_64
【问题讨论】:
-
结构的对齐要求是对齐要求最严格的成员的对齐。在您的 C 实现中,
uint64_t的要求比uint32_t更严格。 -
在没有任何填充的情况下,uint64_t 将从偏移量 12 开始。这会使其未对齐,而不是 8 的倍数,因此编译器会插入 4 个字节的填充以使其达到偏移量 16。16 + 8 = 24 . 不需要额外的填充,当它存储在 B[] 中时仍然是对齐的,所以 24 就足够了。
-
为自己的方便而填充结构的编译器在处理具有刚性未填充内部结构的硬件时将毫无用处。伙计们,这是 C 语言——旨在编写操作系统。