Structure Padding

Last modified by Microchip on 2024/01/19 23:13

Structures allows several related objects, called structure members, to be grouped into one aggregate object and are fully described in the Structures page.

The size of a structure member is identical to the size of an ordinary object with the same type as that member. However, the size of a structure might not be equal to the sum of the sizes of its structure members, it might be larger.

The C Standard requires that structure members have addresses that increase in the order in which they are declared. It also states that the address of a structure’s initial member must be the same as the address of the structure itself. However, compilers are allowed to shift the addresses of subsequent members so that they align with address boundaries that make accessing the member efficient for the target device. These shifts mean that there could be gaps in the structure that are not used for storage but that will contribute to the size of the overall structure.

Never make assumptions about the size of the structures. Always use the sizeof() operator to obtain a structure’s size. Do not assume that a structure member follows immediately in memory after the previous member. Always use the address operator, &, to obtain the address of a structure member.

Structure padding implies that you should be careful using a char pointer to access each byte of a structure since some of those bytes might be padding and hold meaningless values.

Some compilers might pack structure members on an alignment which is equal to the size of that member, so the ordering of the members can affect the structure size. If desired, you can place members with the same size sequentially.

For example, the structure:

1     struct {
2     unsigned char a;
3     unsigned char b;
4     long c;
5     long d;
6 } myStruct;

might be smaller than the following structure which has the same members but which defines them in a different order.

1 struct {
2     unsigned char a;
3     long c;
4     unsigned char b;
5     long d;
6 } myStruct;

For comparison, even though the MPLAB® XC8, XC16, and XC32 C compilers all use a 1-byte-wide char and a 4-byte-wide long type, the size of the last structure shown is 10 bytes when compiling with XC8, 12 bytes when compiling with XC16, and 16 bytes when compiling with XC32. The differences are purely a result of padding between the structure members.

Remember that the compiler must allocate memory for members in the same order as they are defined, so a change in the order of members cannot be performed as an optimization by the compiler.