Skip to content
  • Sergey Bugaev's avatar
    Stop using enums in bitfields · 964affb1
    Sergey Bugaev authored
    The C standard does not specify whether the underlying type of an enum
    is signed or unsigned, and until C23 there was no way to control this
    explicitly. GCC appears to make enums unsigned unless there is a
    negative value among cases of the enum, in which case it becomes signed.
    MSCV appears to make enums signed by default.
    
    A bitfield of an enum type (which is not specificied in the C standard
    either) behaves as if it was an instance of a numeric type with a
    reduced value range. Specifically, a 'signed int val : 2;' bitfield will
    have the possible values of -2, -1, 0, and 1, with the usual wraparound
    behavior for the values that don't fit (although this too is
    implementation-defined).
    
    This causes the following issue, if we have:
    
    typedef enum
    {
      GTK_ZERO,
      GTK_ONE,
      GTK_TWO
    } GtkFoo;
    
    struct _GtkBar
    {
      GtkFoo foo : 2;
    };
    
    and then assign bar.foo = GTK_TWO and read it back, it will have the
    expected value of 2 (aka GTK_TWO) on GCC, but a value of -2 (not
    matching any of t...
    964affb1