带有按位的长枚举

时间:2016-07-25 00:07:50

标签: c++ c++11 enums bit-manipulation flags

在过了第32个标志后,我的enum遇到了问题:

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

知道enums基本上是8bitCONDITION_LUCKY将等于CONDITION_NONE。所以我实施了C++11的{​​{1}}:

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 不相符。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

表达式1 << 32是未定义的行为。来自[expr.shift]:

  

如果右操作数,则行为未定义   是负的,或大于或等于提升的左操作数的位数。

由于1int,因此它只有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,
};