Alignment and Pack
长久以来,我都有这样一个观念,比如 pack(4),就代表着所有数据都是以 4 字节对齐的,直到我有了 64 位机,并且看到下面这个例子:
1 | struct One { |
如果按 4 字节对齐的话,按我的观点,结构体中每一个成员都应该以 4 字节对齐,那么两个都是 4+8+4=16, 结果是对的。
那么如果按 8 字节对齐的话,结果是不是应该是 8+8+8=24?
可是错了。
正确的结果应该是 sizeof(struct One) = 16
,
sizeof(struct Two) = 24
为什么不一样呢?
pragma pack(n)
它指定了结构成员按
n(1,2,4,8,16)字节对齐,但它并不是指结构体中的每个成员都要按 n
对齐,而是按照每个成员的大小(align 值)和 n 相比较小的值对齐。
结构体还有另外一个需求,就是其大小必须是其成员 align 值最大者的整数倍。
那么上面的两个不同就很好解释了:
1 | struct One { |
各种类型变量的 align 值可参考 Data Structure Alignment
再举一个结构体嵌套的例子:
1 | struct Four |
sizeof(struct Four)
和 sizeof(struct Five)
在 4 字节对齐和 8 字节对齐时分别是多少呢?
我们以 8 字节对齐为例:
1 | struct Four |
如果在 32 位机中,struct Four 中,long 长度为 4, 于是
sizeof(struct Four) = 8
, 并且最大 align 值是 4.
于是在 struct Five 中,four 是按 4 字节对齐的,虽然是 pack(8),但
4<8, 所以选 4 作为 align
值,sizeof(struct Five) = 16
.
以上所有实验结果来自 x86_64 GNU/Linux,gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-48)。