Alexandre Severino
Alexandre Severino

Reputation: 1613

Long enum with bitwise

I've been facing a problem with my enum after getting past the 32nd flag:

enum ConditionType_t {
    CONDITION_NONE                          = 0,
    CONDITION_LIGHT                         = 1 << 0,
    CONDITION_INFIGHT                       = 1 << 1,
    CONDITION_MUTED                         = 1 << 2,
    ...
    CONDITION_LUCKY                         = 1 << 32,
}

Knowing that enums are basically 8bit, CONDITION_LUCKY will be equal to the CONDITION_NONE. So I implemented C++11's enum classes:

enum class ConditionType_t : uint64_t {
    CONDITION_NONE                          = 0,
    CONDITION_LIGHT                         = 1 << 0,
    CONDITION_INFIGHT                       = 1 << 1,
    CONDITION_MUTED                         = 1 << 2,
    ...
    CONDITION_LUCKY                         = 1 << 32,
}

Now I get millions of warnings like:

warning C4293: '<<' : shift count negative or too big, undefined behavior

And errors like:

error C2065: 'CONDITION_NONE' : undeclared identifier

Apparently, bit shifting doesn't get along with enum classes.

Any thoughts?

Upvotes: 1

Views: 340

Answers (1)

Barry
Barry

Reputation: 302807

The expression 1 << 32 is undefined behavior. From [expr.shift]:

The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

Since 1 is an int, it only has 32 bits. Even if this wasn't undefined, you wouldn't get the value you wanted either, since the type of 1 << 32 is int, which can't hold a 33-bit value anyway.

You'll need to use an uint64_t from the start:

enum class ConditionType_t : uint64_t {
    CONDITION_NONE                          = 0,
    CONDITION_LIGHT                         = 1ULL << 0,
    CONDITION_INFIGHT                       = 1ULL << 1,
    CONDITION_MUTED                         = 1ULL << 2,
    ...
    CONDITION_LUCKY                         = 1ULL << 32,
};

Upvotes: 4

Related Questions