繁体   English   中英

嵌套结构填充 - C - 64位 - linux

[英]Nested structure padding - C - 64 bit - linux

我在C中有以下嵌套结构(64位)

    typedef struct {
        int a;
        int b;
        int c;
        struct {
            int ab;
            long bc;
        }
        int d;
    } Test;

I see that,
a = 4 bytes
b = 4 bytes
c = 4 bytes
padding1 = 4 bytes 
inner structure = 16 bytes ( 4 bytes for ab, 4 bytes padding, 8 bytes for bc)
d = 4 bytes
padding2 = 4 bytes

sizeof(Test)返回40个字节。

我的问题:

  1. padding1 - >为什么这4个字节? 这是因为内部结构本身应该对齐吗? (另外,它是与8字节(长)还是16字节(内部大小)边界对齐。?)

  2. padding2 - >这是4字节填充,因为在结构内部完成了最大的对齐(这是8)??

谢谢,

  1. padding1 - >为什么这4个字节? 这是因为内部结构本身应该对齐吗? (另外,它是与8字节(长)还是16字节(内部大小)边界对齐。?)

这是因为内部struct应该是8字节对齐的,因此long可以可靠地进行8字节对齐。

  1. padding2 - >这是4字节填充,因为在结构内部完成了最大的对齐(这是8)??

它是这样的,整个struct的大小是八个字节的倍数,因此内部struct可以在八字节边界上适当地对齐。

在这种特殊情况下,如果匿名struct成员可以与独立struct不同地处理,则只需要四个字节的填充就可以满足对齐要求,但是6.7.2.1

14结构或联合对象的每个非位字段成员都以适合其类型的实现定义方式对齐。

禁止那样的。 因此,为了减小struct的大小,程序员需要重新排列它,将奇数个int成员移动到内部struct (或者生成int ab;以及long bc;直接成员的Test而不通过匿名struct )。

填充是非常依赖平台和编译器的,即使您看到的行为非常常见。

通常(这不是C标准所说的),编译器会对齐结构的成员,以减少内存访问次数。 对于64位x86,内存访问总是获取8个字节,与64位边界对齐。 换句话说,如果在地址0x1010AA45访问1个字节,CPU将实际从地址0x01010AA40的 (高速缓存)内存中取出8个字节。

为了实现这样的规则,如果成员是N字节长,则编译器通常将N舍入到下一个2的幂,并将该成员与64位平台上的此类大小或8字节对齐,无论哪个更小。 大多数编译器允许通过#pragma或配置调整此类规则。

我相信你的编译器会添加Padding1,因为它有一个规则可以将所有结构与8字节边界对齐,无论它们有多大。 或者,它也可以引入它,因为内部结构大于4个字节,因此需要对齐到8个字节。

Padding2可能是因为您可以创建一个struct Test数组。 为了保证所有结构都正确地对齐到8字节边界 - 而不仅仅是数组中的第一项 - 最后定义了填充。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM