联盟规模大于预期。 如何在这里进行类型对齐?

#include  union u1 { struct { int *i; } s1; struct { int i, j; } s2; }; union u2 { struct { int *i, j; } s1; struct { int i, j; } s2; }; int main(void) { printf(" size of int: %zu\n", sizeof(int)); printf("size of int pointer: %zu\n", sizeof(int *)); printf(" size of union u1: %zu\n", sizeof(union u1)); printf(" size of union u2: %zu\n", sizeof(union u2)); return 0; } 

结果是:

 $ gcc -O -Wall -Wextra -pedantic -std=c99 -o test test.c $ ./test size of int: 4 size of int pointer: 8 size of union u1: 8 size of union u2: 16 

为什么在union u2的嵌套struct s1中添加一个4字节的整数会使整个联合的大小增加8个字节?

由于对齐约束,struct u2.s2是16个字节。 编译器保证如果你创建这样的结构数组,每个指针将在8字节边界上对齐。 字段*i占用8个字节,然后j占用4个字节,编译器插入4个字节的填充。 因为结构是16个字节,所以包含它的联合也是16个字节。

那是因为编译器需要保持整个结构(以及联合)与8个字节对齐 – 因为你有一个指针在里面。 (在你的情况下是8字节)

因此,即使使用额外的int仅添加4个字节,struct-alignment也会强制所有内容与8个字节对齐 – 因此+8将总大小调整为16个字节。

结果是:

 struct { int *i, j; } s1; 

大小为16个字节。 由于联合必须至少与最大元素一样大,因此它也最多被强制为16。

http://en.wikipedia.org/wiki/Data_structure_alignment

由于指针在您的平台上是8个字节,因此很可能还需要8个字节的对齐。 因此,当添加另外4个字节时,结构不能仅具有12个字节的大小,在这种情况下,说明u2的数组的各个元素将不能在8字节边界处正确对齐,这对于指针成员是必要的。 所以你需要将它的大小增加到8的下一个倍数,即16。额外的4个字节只是未使用/未定义。