In case you allocate individual variables, the compiler is free to allocate them as it pleases, at any address or in any order. Naturally it will do this with alignment in mind, but also perhaps with optimizer settings: optimize for speed vs size. Depending on CPU, it may or may not support misaligned access, or it might not have alignment requirements at all.
When programming hardware-related programs, there is often a need to allocate variables in a certain order. The code might be modelling a data communications protocol, a hardware register map, an image memory layout etc etc. The only mechanism C provides to guarantee an order of least significant -> most significant address allocation is struct
. Therefore, C explicitly forbids the compiler to change allocation order of the members of a struct
.
(In theory, C is also supposed to support bit-field members of a struct
, though in practice the feature is so under-specified by the standard that it can't be used reliably.)
Therefore padding optimization of a struct
by the compiler isn't possible - it has to allocate the members in the order specified by the programmer, even if that means adding lots of dead padding bytes to suit alignment. This problem only exists if the struct uses members smaller than the alignment requirement(s) supported by the CPU, however.
One trick to memory-optimize when struct order of allocation isn't needed, is that instead of having a struct with n members, create n different arrays, each array having the type of one of the members. The array index then becomes the association between which array members that belong to the same group, rather than the mystruct.member
syntax.
There are also non-standard ways to disable padding, but they aren't portable and usually a last resort - since the padding was added for a reason. With or without padding enabled, if you need truly portable structs, you may have to write manual serialization/deserialization routines that memcpy
member by member.