size of the union larger than expected. How is type alignment done here?

Advertisement
 #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; }  #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; } #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; } #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; } 

Result in:

 $ 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 

Why does adding an integer of 4 bytes to the nested s1 structure of union u2 increase the size of the union in its 8-byte set?

The answer

This is because the compiler must keep the whole structure (and union) aligned to 8 bytes - due to the fact that you have a pointer inside it. (which is 8 bytes in your case)

So even if you only add 4 bytes with the additional int , struct-alignment forces everything to align to 8 bytes, hence the +8 to bring the total size to 16 bytes.

The result is that:

 struct { int *i, j; } s1; 

has a size of 16 bytes. Since a union must be at least as large as the most important element, it is also forced to 16.

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