#include <stdio.h>
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个字节?
答案 0 :(得分:8)
由于对齐约束,结构u2.s2
是16个字节。编译器保证如果你创建这样的结构数组,每个指针将在8字节边界上对齐。字段*i
占用8个字节,然后j
占用4个字节,编译器插入4个字节的填充。因为结构是16个字节,所以包含它的联合也是16个字节。
答案 1 :(得分:4)
这是因为编译器需要保持整个结构(以及联合)与8个字节对齐 - 这是因为你有一个指针在里面。 (在你的情况下是8字节)
因此,即使你只用额外的int
添加4个字节,struct-alignment强制所有内容都与8个字节对齐 - 因此+8将总大小调整为16个字节。
结果是:
struct {
int *i, j;
} s1;
的大小为16个字节。由于联合必须至少与最大元素一样大,因此它也被强制为16。
答案 2 :(得分:2)
由于指针在您的平台上是8个字节,因此很可能还需要8个字节的对齐。因此,当添加另外4个字节时,结构不能只有12个字节的大小,在这种情况下,u2
s数组的各个元素将无法在8字节边界处正确对齐,这对于指针成员。所以你需要将它的大小增加到8的下一个倍数,即16。额外的4个字节只是未使用/未定义。