Firstly, while the specifics of padding are left up to the compiler, the OS also imposes some rules as to alignment requirements. This answer assumes that you are using gcc, though the OS may vary
To determine the space occupied by a given struct and its elements, you can follow these rules:
First, assume that the struct always starts at an address that is properly aligned for all data types.
Then for every entry in the struct:
- The minimum space needed is the raw size of the element given by
sizeof(element)
.
- The alignment requirement of the element is the alignment requirement of the element's base type.
Notably, this means that the alignment requirement for a
char[20]
array is the same as
the requirement for a plain char
.
Finally, the alignment requirement of the struct as a whole is the maximum of the alignment requirements of each of its elements.
gcc will insert padding after a given element to ensure that the next one (or the struct if we are talking about the last element) is correctly aligned. It will never rearrange the order of the elements in the struct, even if that will save memory.
Now the alignment requirements themselves are also a bit odd.
- 32-bit Linux requires that 2-byte data types have 2-byte alignment (their addresses must be even). All larger data types must have 4-byte alignment (addresses ending in
0x0
, 0x4
, 0x8
or 0xC
). Note that this applies to types larger than 4 bytes as well (such as double
and long double
).
- 32-bit Windows is more strict in that if a type is K bytes in size, it must be K byte aligned. This means that a
double
can only placed at an address ending in 0x0
or 0x8
. The only exception to this is the long double
which is still 4-byte aligned even though it is actually 12-bytes long.
- For both Linux and Windows, on 64-bit machines, a K byte type must be K byte aligned. Again, the
long double
is an exception and must be 16-byte aligned.