c++bit-fieldsstatic-assert

Is there a way to detect padding bits in a bitfield?


I extensively utilize bit-fields in my C++ embedded application, and I have encountered a problem. Below is an example showcasing my usage:

struct {
    uint8_t /* Reserved */ : 3;
    uint8_t foo : 3;
    uint8_t bar : 3;
} bits;

To ensure that I have correctly specified the number of bits in a bit-field, I employ the static_assert(...) mechanism:

// assertion fails due to 1 extra bit
static_assert(sizeof(bits) == sizeof(uint8_t));

This approach allows me to verify if I have surpassed the size limitation. However, I am currently unable to determine whether there are any padding bits in the struct. Is there a method to detect such situations?

struct {
    uint8_t /* Reserved */ : 3;
    uint8_t foo : 3;
    uint8_t bar : 1;
} bits;
// assertion passes, but I want it to fail, because one bit is padding
static_assert(sizeof(bits) == sizeof(uint8_t)); 

Solution

  • Clang's -Wpadded does exactly what you want.

    If you are not using clang, you can rename your unnamed bitfields into something like Reserved1 through ReservedN. Then you can use std::has_unique_object_representations which tells you if your class has padding or not:

    struct {
        [[deprecated("This field should not be used")]] uint8_t Reserved1 : 2;
        uint8_t foo : 3;
        uint8_t bar : 3;
    } bits;
    
    // If `Reserved1` had a bitsize of 3, it would have padding and this would fail
    static_assert(std::has_unique_object_representations_v<decltype(bits)>);