Search code examples
c++cenumsbit-fields

Is it safe to use an enum in a bit field?


Say, I've got the following struct:

typedef struct my_struct{
    unsigned long       a;
    unsigned long       b;
    char*               c;
    unsigned int        d1  :1;
    unsigned int        d2  :4;
    unsigned int        d3  :4;
    unsigned int        d4  :23;
} my_type, *p_type;

The field d3 is currently defined by #defines that reach from 0x00 until 0x0D.

Actually, d3 is an enumeration. So it's tempting to go ahead and replace

    unsigned int        d3  :4;

by

    my_enum             d3  :4;

Is this safe/allowed?

The code has to compile with various

  • compilers (GCC, Visual Studio, embedded stuff)
  • platforms (Win32, Linux, embedded stuff)
  • configurations (compile as C, compile as C++)

Obviously, I could leave the definition of d3 as it is and use the enum in my code, assign it to d3 and so on but that's not going to work with C++.


Solution

  • Answer will be different for C and C++, this is one for C.

    In C bitfields are restricted to signed int, unsigned int, _Bool and int which in this context can be any of the first two. Compiler implementors can add to that list to their liking but are required to document the types that they support.

    So to answer your question, if you want to be absolutely sure that your code is portable to all C compilers, no, using an enum type is not an option.

    The corresponding paragraph from the current standard reads:

    A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int, unsigned int, or some other implementation-defined type. It is implementation-defined whether atomic types are permitted.