带位的长枚举

Long enum with bitwise

我的 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基本上就是8bitCONDITION_LUCKY就等于CONDITION_NONE。所以我实现了 C++11enum 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 不相容。

有什么想法吗?

表达式1 << 32 是未定义的行为。来自 [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.

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