c++unionsbit-fields

Union of unsigned short and anonymous bitfield


Minimal example:

union v1_t
{
    struct {
        unsigned int d1 : 4;
        unsigned int d2 : 4;
        unsigned int : 8;
    };
    unsigned short data;
};

union v2_t
{
    unsigned short data;
    struct {
        unsigned int d1 : 4;
        unsigned int d2 : 4;
        unsigned int : 8;
    };
};

int main()
{
    v1_t v1 {256}; // gets truncated to 0. This is the equivalent of v1_t {.d1=256}
    v2_t v2 {256};
}

The exact representation of my bitfields is different and is irrelevant here. The important part is that v2_t works as I expect and require (2 Bytes info with bitfields), butv1_t is truncating the data into 4 bits, exactly d1?


Solution

  • The uniform initialization of the fields of each union will follow the order of the declared members.

    For instance, v1_t {256}; is the equivalent of v1_t {.d1=256}; (C++20) which will obviously truncate the data (put down this way, the current behavior became obvious).

    With v2_t on the other hand, the first data member is data, hence v2_t {256}; is the equivalent of v2_t {.data=256}; which is yielding the result and behavior I expected.

    v1_t enables brace elision such as {11, 2} for d1 and d2 fields, respectively, but I have many different bit fields of different sizes and initialization must remain consistent from type to type.

    The current standard in use in my project is C++17, hence the {.data} initialization possibility is not available and that is the reason why I consider v2_t the one providing the "expected" behavior.