在C ++中,枚举的大小是否必须等于其基础类型的大小?

时间:2017-11-22 21:25:05

标签: c++ c++14 language-lawyer

我经常假设枚举的大小与其基础类型的大小相同。但它是否由标准规定?

标准(C ++ 14,n4296)表示每个枚举都有一个基础类型(7.2 / 5)。该标准还说对象表示为字节序列,并且对象的大小与其表示相关:

  

3.9 / 4类型为T的对象的对象表示是N的序列   由类型T的对象占用的unsigned char对象,其中N等于   的sizeof(T)。

     

5.3.3 / 1 sizeof运算符产生对象中的字节数   表示其操作数。

但是,我无法在枚举的基础类型和对象表示之间找到任何关系。有没有?如果没有,那么我认为枚举的sizeof不必是其基础类型的sizeof。

所以我的问题是:

  1. 枚举的基础类型与其对象表示之间是否有任何关系?

  2. 对于任何枚举E,标准是否真的需要sizeof(std::underlying_type_t<E>) == sizeof(E)

2 个答案:

答案 0 :(得分:1)

取自:What is the underlying type of a c++ enum?,较旧的C ++标准规定为7.2 / 5:

  

枚举的基础类型是可以的整数类型   表示枚举中定义的所有枚举器值。它是   实现定义的哪个整数类型用作底层   枚举的类型,但基础类型不应该是   大于int,除非enurator的值不适合   int或unsigned int。如果枚举器列表为空,则为底层   类型就好像枚举有一个值为0的枚举器。   sizeof()的值应用于一个枚举类型,一个对象   枚举类型或枚举器是应用的sizeof()的值   基础类型。

draft n4606我最接近的是7.2 / 7 + 8,其中说明:

  

7)对于其基础类型未修复的枚举,基础   type是一个整数类型,可以表示所有枚举器值   在枚举中定义。如果没有整数类型可以代表所有   枚举值,枚举是不正确的。它是   实现定义的哪个整数类型用作底层   除了底层类型不应大于int之外的类型   除非枚举器的值不能适合int或unsigned   INT。如果枚举器列表为空,则基础类型就像是   枚举有一个值为0的枚举器。

     

8)对于其基础类型是固定的枚举,枚举的值是   基础类型的值。否则,对于枚举在哪里   emin是最小的枚举器,emax是最大的,值   枚举是bmin到bmax范围内的值,定义为   如下:对于二进制补码表示,K为1,对于a,则为0   一些补充或符号幅度表示。 bmax是   最大值大于或等于max(| emin | - K,| emax |)和   等于2M - 1,其中M是非负整数。 bmin为零   emin是非负的,否则 - (bmax + K)。的大小   最小的位域,足以容纳所有的值   如果bmin为零,则枚举类型为max(M,1),否则为M + 1。它   可以定义具有未定义的值的枚举   任何一名调查员。如果枚举器列表为空,则值为   枚举就像枚举有一个枚举器一样   值0

另一方面,它似乎足够接近,另一方面,sizeof()运算符的特定需求被删除了。 我仍然认为说这两个问题的答案是肯定的是足够安全。

答案 1 :(得分:1)

我已经搜索了标准,这是我能找到的最好的(我知道这可能不够):

底层类型在此处隐式定义(C ++ 14的3.9.1 / 5):

  

类型wchar_t是一种不同的类型,其值可以表示不同   指定最大扩展字符集的所有成员的代码   在受支持的语言环境中(22.3.1)。类型wchar_t 应具有相同的   大小,签名和对齐要求(3.11)作为其中之一   其他整数类型,称为其基础类型。类型char16_t和   char32_t表示具有相同大小,签名和的相同类型   对齐分别为uint_least16_t和uint_least32_t   &lt; cstdint&gt;,称为基础类型。

此定义约为wchar_t,但我认为可以肯定地说基础类型的定义。 (至少,这是标准给出的最佳定义。此外,底层类型的C ++ 14标准索引在这里引用)

这意味着:

  1. 表示必须相同

  2. 尺寸必须相等

  3. (但我认为底层类型应该在标准中更好地定义)