已签名基础类型枚举的位域溢出

Overflow on bitfield for signed underlying type enum

这仅适用于 C++11:

如果我有一个像下面这样的常规枚举:

enum TestType
{
Test0 = 0,
Test1,
Test2,
Test3,
Test4,
Test5,
Test6,
Test7
}

和像这样的打包结构:

struct
{
TestType a : 3
uint32_t b : 5
} TestStruct;

TestStruct.a 是否保证在访问时等于任何有效分配的枚举值?或者编译器是否有可能分配一个带符号的基础类型,然后将位域 a 视为范围为 -4 到 3.

Is TestStruct.a guaranteed to be equal to its assigned enum value?

没有。您默认初始化 TestStruct。如果这是在全局 space 中,那么它将初始化为零,并且 ab 都将为 0.

如果这是在块 space 中,则不会发生初始化,这意味着 ab 具有未指定的值。您所知道的是该值将在该类型的可表示范围内。 Test0 的值为 0 在这里根本不起作用。

如果你有

TestStruct{};

然后 ab 将为零,因为您正在对对象进行值初始化,在这种情况下,这意味着您将其初始化为零。你也可以使用

TestStruct{value1, value2};

ab赋值。


关于 a 是否可以存储 TestType 的所有值的问题,我们必须查看 [class.bit]/4 哪个状态

[...]If the value of an enumerator is stored into a bit-field of the same enumeration type and the number of bits in the bit-field is large enough to hold all the values of that enumeration type ([dcl.enum]), the original enumerator value and the value of the bit-field shall compare equal.

强调我的

枚举的值由[dcl.enum]/8定义为

For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type. Otherwise, for an enumeration where emin is the smallest enumerator and emax is the largest, the values of the enumeration are the values in the range bmin to bmax, defined as follows: Let K be 1 for a two's complement representation and 0 for a ones' complement or sign-magnitude representation. bmax is the smallest value greater than or equal to max(|emin − K, |emax|) and equal to 2M−1, where M is a non-negative integer. bmin is zero if emin is non-negative and −(bmax+K) otherwise. The size of the smallest bit-field large enough to hold all the values of the enumeration type is max(M,1) if bmin is zero and M+1 otherwise. It is possible to define an enumeration that has values not defined by any of its enumerators. If the enumerator-list is empty, the values of the enumeration are as if the enumeration had a single enumerator with value 0

所以在这种情况下 emin 是 0 并且 emax 7 所以 bmin为 0 并且 bmax 等于或大于 max(|emin| − K, |emax|) 即 7。因为它必须等于 2M−1 如果我们对 M 使用 3 那么我们也得到 7。

我们有

The size of the smallest bit-field large enough to hold all the values of the enumeration type is max(M,1) if bmin is zero and M+1 otherwise.

和 bmin 是零所以我们需要的最小位域是 3 你有所以你保证 TestType 的所有值都适合 a.