Search code examples
c++cstructpaddingbit-fields

Offset in a struct with bit fields


If we have a struct with bit fields, then how are the subsequent members aligned in the struct? Consider the following code:

struct A{
    int a:1;
    char b;     // at offset 1
};

struct B{
    int a:16;
    int b: 17;
    char c;     // at offset 7
};

printf("Size of A: %d\n", (int)sizeof(struct A));
printf("Offset of b in A: %d\n", (int)offsetof(struct A, b));

printf("Size of B: %d\n", (int)sizeof(struct B));
printf("Offset of c in B: %d\n", (int)offsetof(struct B, c));

Output:

Size of A: 4
Offset of b in A: 1
Size of B: 8
Offset of c in B: 7

Here, in the first case, b is allocated just in the 2nd byte of the struct without any padding. But, in the 2nd case, when bit fields overflow 4 bytes, c is allocated in the last (8th) byte.

What is happening in the 2nd case? What is the rule for padding in structs involving bit fields in general?


Solution

  • how are the subsequent members aligned in the struct?

    Nobody knows. This is implementation-defined behavior and thus compiler-specific.

    What is happening in the 2nd case?

    The compiler may have added padding bytes or padding bits. Or the bit order of the struct might be different than you expect. The first item of the struct is not necessarily containing the MSB.

    What is the rule for padding in structs involving bit fields in general?

    The compiler is free to add any kind of padding bytes (and padding bits in a bit field), anywhere in the struct, as long as it isn't done at the very beginning of the struct.

    Bit-fields are very poorly defined by the standard. They are essentially useless for anything else but chunks of boolean flags allocated at random places in memory. I would advise you to use bit-wise operators on plain integers instead. Then you get 100% deterministic, portable code.