Search code examples
c++visual-c++bit-fields

MSVC 1 bit enum type equals -1 and equality test fails


I have defined a bitfield of enum types to match a set of bits in an embedded system. I'm trying to write a test harness in MSVC for the code, but comparing what should be equal values fails.

The definition looks like this:

typedef enum { SERIAL, PARALLEL } MODE_e;
typedef union {
    struct {
        TYPE_e      Type    : 1;    // 1
        POSITION_e  1Pos    : 1;    // 2
        POSITION_e  2Pos    : 1;    // 3
        bool        Enable  : 1;    // 4
        NET_e       Net     : 1;    // 5
        TYPE_e      Type    : 1;    // 6
        bool        En      : 1;    // 7
        TIME_e      Time    : 3;    // 8-10
        MODE_e      Mode    : 1;    // 11
        bool        TestEn  : 1;    // 12
        bool        DelayEn : 1;    // 13
        MODE_e      Mode    : 1;    // 14
        bool        xEn     : 1;    // 15
        MODE_e      yMode   : 1;    // 16
        bool        zEnable : 1;    // 17
    } Bits;
    uint32_t Word;
} BITS_t;

Later the following comparison fails:

Store.Bits.Mode = PARALLEL;
if (store.Bits.Mode == PARALLEL)
    ...

I examined the Mode bool in the debugger, and it looked odd. The value of Mode is -1.

It's as if MSVC considers the value to be a two's complement number, but 1 bit wide, so 0b1 is decimal -1. The enum sets PARALLEL to 1, so the two do not match.

The comparison works fine on the embedded side using LLVM or GCC.

Which behavior is correct? I assume GCC and LLVM have better support for the C standards than MSVC in areas such as bit fields. More importantly, can I work around this difference without making major changes to the embedded code?


Solution

  • A simple fix I came up with, which is only valid for MSVC and GCC/LLVM, is:

    #ifdef  _WIN32
    #define JOFF        0
    #define JON         -1
    #else
    #define JOFF        0
    #define JON         1
    #endif
    
    typedef enum { SERIAL = JOFF, PARALLEL = JON } TEST_MODE_e;