Actually, here's some updated code that shows the offsets from the base of the structure.
Code:
#include <stdio.h>
#include <stddef.h>
struct z
{
char a[20];
int b;
union
{
double c;
struct
{
char d[15];
float e;
} x;
} y;
};
int main(void)
{
struct z test;
printf("sizeof(z) == %zd\n", sizeof(test));
printf("sizeof(y) == %zd\n", sizeof(test.y));
printf("sizeof(x) == %zd\n", sizeof(test.y.x));
ptrdiff_t base = (ptrdiff_t ) &test;
ptrdiff_t a = (ptrdiff_t ) &(test.a);
ptrdiff_t b = (ptrdiff_t ) &(test.b);
ptrdiff_t c = (ptrdiff_t ) &(test.y.c);
ptrdiff_t d = (ptrdiff_t ) &(test.y.x.d);
ptrdiff_t e = (ptrdiff_t ) &(test.y.x.e);
printf("a - base == %td\n", a - base);
printf("b - base == %td\n", b - base);
printf("c - base == %td\n", c - base);
printf("d - base == %td\n", d - base);
printf("e - base == %td\n", e - base);
return 0;
}
Output :
Code:
sizeof(z) == 48
sizeof(y) == 24
sizeof(x) == 20
a - base == 0 // a starts at start of structure
b - base == 20 // b begins 20 bytes after
c - base == 24 // c starts where it should
d - base == 24 // d also starts where it should
e - base == 40 // then, 16 bytes later, we have e (15 would be aligned to 16)
As for why the total is 48 and not 44, I'm not sure considering most floats are 4 bytes. Again, probably weird compiler alignment but this sort of shows what's going on.