2016-07-25 3 views
1

Я столкнулся с проблемой с моим enum после обходя 32-я флага:Длинное перечисление с побитовым

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

Зная, что enums в основном 8bit, CONDITION_LUCKY будет равно CONDITION_NONE. Так что я реализовал 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, 
} 

Теперь я получаю миллионы предупреждений, как:

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

И ошибки как:

error C2065: 'CONDITION_NONE' : undeclared identifier 

Видимо, немного манетки не ладят с enum classes.

Любые мысли?

+2

Что заставляет вас думать, что "' enums' в основном '8bit'"? – Dmitri

ответ

4

Выражение 1 << 32 - это неопределенное поведение. Из [expr.shift]:

поведение не определено, если правый операнд отрицательный, либо больше или равно длине в битах продвигаемого левого операнда.

С 1 является int, он имеет только 32 бита. Даже если это не было неопределенным, вы не получите желаемого значения, так как тип 1 << 32 равен int, который в любом случае не может хранить 33-битное значение.

Вы должны будете использовать uint64_t с самого начала:

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, 
};