You need to consider what the happens if you allocate an array of these structures with malloc()
:
structc_t *p = malloc(2 * sizeof *p);
Consider a platform where sizeof(double) == 8
, sizeof(int) == 4
and the required alignment of double
is 8. malloc()
always returns an address correctly aligned for storing any C type - so in this case a
will be 8 byte aligned. The padding requirements then naturally fall out:
In order for a[0].d
to be 8-byte aligned, there must therefore be 7 bytes of padding after a[0].c
;
In order for a[1].d
to be 8-byte aligned, the overall struct size must be a multiple of 8, so there must therefore be 4 bytes of padding after a[0].s
.
If you re-order the struct
from largest to smallest:
typedef struct structc_tag
{
double d;
int s;
char c;
} structc_t;
...then the only padding required is 3 bytes after .c
, to make the structure size a multiple of 8. This results in the total size of the struct being 16, rather than 24.
double
entities should be aligned to addresses divisible by 8, otherwise the FPU might become unhappy while trying to load the value from memory. A very slow unaligned load must be issued in such cases (and some platforms do not support unaligned access at all). This is especially true in 64-bit mode on x64 CPUs where math is done primarily using SSE. Last four bytes are there to guarantee correct alignment when stacking many such structures one after another (e.g. in an array ofstruct_t
). – Hristo Ilievsizeof()
when checking the number of bytes an object uses -- even for primitives like int. – Pyrce