带符号的基础类型枚举的位域上的溢出

时间:2018-08-28 18:05:47

标签: c++ c++11 enums bit-fields

这仅适用于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。

1 个答案:

答案 0 :(得分:4)

  

是否保证TestStruct.a等于其分配的枚举值?

不。您默认初始化TestStruct。如果在全局空间中,则它将初始化为零,并且ab都将为0。

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

如果有

0

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

b

TestStruct{value1, value2}; a分配特定的值。


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

  

[...]如果将枚举器的值存储到相同枚举类型的位域中,并且该位域中的位数大到足以容纳所有值该枚举类型([dcl.enum]),原始枚举器值和位字段的值应比较相等。

强调我的

,并且[dcl.enum]/8将枚举的值定义为

  

对于基础类型固定的枚举,该枚举的值是基础类型的值。否则,对于e min 是最小的枚举数和e max 的枚举    是最大的,枚举的值是范围内的值   b min 到b max ,定义如下:令K为2的补码表示,TestType代表1的补码或符号幅度表示。 b max 是大于或等于max(| e min -K,| e max |)且等于2 < sup> M -1,其中M为非负整数。如果e min 为非负数,则b min 为零,否则为-(b max + K)。如果b min 为零,则足以容纳枚举类型的所有值的最小位域的大小应为max(M,1),否则为M + 1。可以定义一个其枚举数未定义的枚举。如果枚举数列表为空,则枚举的值就像枚举有一个值为0的单个枚举数

因此,在这种情况下,e min 为0,e max 为7,因此b min 为0,b max 等于或大于7的max(| e min |-K,| e max |),因为它必须等于2 M −1,如果我们对M使用3,那么我们也得到7。

我们有

  

如果b min 为零,则足以容纳枚举类型的所有值的最小位域的大小应为max(M,1),否则为M + 1。

和b min 为零,因此我们需要的最小位域为3,因此可以确保0的所有值都适合TestType