Search code examples
c++language-lawyerbit-fieldsmemory-layout

How do bit fields interplay with bits padding in C++


See the C version of this questions here.

I have two questions concerning bit fields when there are padding bits.

Say I have a struct defined as

struct T { 
    unsigned int x: 1; 
    unsigned int y: 1;
};

Struct T only has two bits actually used.

Question 1: are these two bits always the least significant bits of the underlying unsigned int? Or it is platform dependent?

Question 2: Are those unused 30 bits always initialized to 0? What does the C++ standard say about it?


Solution

  • Question 1: are these two bits always the least significant bits of the underlying unsigned int? Or it is platform dependent?

    Very platform dependent. The standard even has a note just to clarify how much:

    [class.bit]

    1 ...Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit. [ Note: Bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others.  — end note ]

    You can't assume much of anything about the object layout of a bit field.

    Question 2: Are those unused 30 bits always initialized to 0? What does the C++ standard say about it?

    Your example has a simple aggregate, so we can enumerate the possible initializations. Specifying no initializer...

    T t;
    

    ... will default initialize it, leaving the members with indeterminate value. On the other hand, if you specify empty braces...

    T t{};
    

    ... the object will be aggregate initialized, and so the bit fields will be initialized with {} themselves, and set to zero. But that applies only to the members of the aggregate, which are the bit fields. It's not specified what value, if any, the padding bits take. So we cannot assume they will be initialized to zero.