Search code examples
cstructunionsbit-fields

Bitfields in C with struct containing union of structs


Hm... why is it that, when I print sizeof(struct MyStruct), it outputs 3 (instead of 2) for this code?

#pragma pack(push, 1)
    struct MyStruct
    {
        unsigned char a : 6;
        union
        {
            struct
            {
                unsigned int b : 9;
            };
        };
    };
#pragma pack(pop)

In case it matters, I'm running MinGW GCC 4.5.0 on Windows 7 x64, but honestly, the result is weird enough for me that I don't think the compiler and the OS matter too much here. :\


Solution

  • You can't have the field starting at an address that is not byte aligned. You're expecting:

    6 bits + 9 bits -> 15 bits -> 2 bytes
    

    but what you're getting is:

    6 bits -> 1 byte
    9 bits -> 2 bytes
    total ->  3 bytes
    

    The data is being stored as:

    | 1 byte | 2 byte |3 byte | 
     aaaaaaXX bbbbbbbb bXXXXX  
    

    when you were expecting:

    | 1 byte | 2 byte |
     aaaaaabb bbbbbbbX  
    

    edit: To clarify based on the comments below:

    The union (and the containing struct) must be byte aligned. It doesn't matter that the contents are only 9 bits, the union/struct itself is a full 16 bits. Notice that you cannot do the following:

    struct MyStruct
    {
        unsigned char a : 6;
        union
        {
            struct
            {
                unsigned int b : 9;
            } c:9;
        } d:9;
    };
    

    As C won't let you specify the entire struct's bit-size.