Skip to main content

Layout, Padding & offsetof

intermediate16 min readLesson 101 of 148

Why sizeof a struct is not the sum of its members, and how to measure layout instead of guessing.

The compiler may insert holes

Each member must sit at an offset that is a multiple of its alignment. The compiler inserts invisible padding to make that true, and pads the struct's total size so arrays of it stay aligned:

struct Packed {
    char  c;      /* offset 0 */
                  /* 3 bytes padding */
    int   i;      /* offset 4 */
    char  d;      /* offset 8 */
                  /* 3 bytes padding (so sizeof works for arrays) */
};                /* sizeof == 12, not 6 */

Reordering members largest-first usually shrinks the struct. But do not memorize layouts โ€” measure them:

#include <stddef.h>
offsetof(struct Packed, i)   /* == 4: the offset as actually compiled */
sizeof(struct Packed)        /* == 12 */

offsetof answers "where is this member really" under this compiler, this standard, these flags. Code that files into binary formats uses it โ€” or better, uses it in a _Static_assert to fail the build if the layout ever drifts:

_Static_assert(offsetof(struct Header, magic) == 0, "header layout");

Alignment is a property of types

int aligns to 4, double to 8, pointers to 8 (on 64-bit). The struct's own alignment is the max of its members'. That is why member order matters and why the trailing padding exists.

Now practice

Layout GymMeasure struct layout with offsetof and sizeof; assert it.2 challenges ยท ยท ~22 min