← Structs and UnionsC PROGRAMMING 1.4.E

Bit Fields

Packing sub-byte fields into a struct — the register-map pattern.

StatusCollected
NotesChapter test: 4/5

This is the one that actually explains why hardware register documentation always comes with a bit diagram — bit fields are how that diagram becomes a struct.

struct status_reg {
    unsigned int enable : 1;    /* 1 bit */
    unsigned int mode   : 2;    /* 2 bits */
    unsigned int        : 1;    /* 1 padding bit, unnamed */
    unsigned int errcode: 4;    /* 4 bits */
};

struct status_reg r;
r.enable = 1;
r.mode = 3;

The : n after each member tells the compiler to pack it into exactly n bits instead of a full unsigned intenable and mode and errcode here all share the same underlying word instead of each taking 4 bytes. It's precisely the same layout a register datasheet describes — "bit 0 is enable, bits 1-2 are mode" — just expressed as C instead of a table.

The catch is that exact bit ordering and padding within the word is implementation-defined — portable across compilers and architectures it is not, which is part of why a lot of real driver code still does manual shifting and masking on a plain integer instead of trusting bit-field layout.

Notes from readers

Comments — via GitHub