不应该打印代码" 1 1"而不是" 4 4"?

时间:2014-04-27 12:38:49

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

根据§7.2/ 5和§7.2/ 6不应该code below打印1 1而不是4 4

#include <iostream>
enum A { a = (char)1, b, c };   //  underlying type is not fixed

int main() {
    std::cout << sizeof(a) << ' ' << sizeof(A) << '\n';
}

修改

  

来自§7.2/ 5:

     

如果未修复基础类型,则每个枚举器的类型为   其初始化值的类型:

     

- 如果为枚举器指定了初始值设定项,则进行初始化   value与表达式和常量表达式具有相同的类型   应是一个整数常数表达式(5.19)。

4 个答案:

答案 0 :(得分:20)

如果您没有明确定义基础类型,那么编译器可以自由选择适合这些值的整数类型。要在C ++ 11中设置基础类型,可以使用:

enum A : char { a = 1, b, c }; 
       ^^^^^^

如果char

,您的方式不会强制编译器使用int

答案 1 :(得分:5)

这是实现定义:enum的所有值都适合,例如uint8_t,这并不会强制编译器选择枚举的单字节表示。

  

枚举的基础类型是一个整数类型,可以表示枚举中定义的所有枚举器值。 实现定义了哪个整数类型用作枚举的基础类型,除了基础类型不应大于int,除非枚举器的值不能适合int或{{1 }}。 (重点补充)

在您的情况下,编译器实现者似乎选择了一个unsigned int,它在您的平台上占用了四个字节 - 这是一个非常有效的选择。

答案 2 :(得分:4)

您引用的条款7.2 / 5描述了枚举器的类型。但是枚举器只是枚举定义的一部分。枚举的基础类型足以容纳所有枚举器的值,受7.2 / 6的限制:

  

它是实现定义的,使用整数类型作为基础类型,除了基础类型不应大于int,除非枚举器的值不能适合int或{{ 1}}。

因此可以保证您的基础类型不大于unsigned int(因为int可以表示0,1和2)。确实,第一个枚举数的类型在枚举定义中是int,但所有实际的枚举值都是char类型。要实际控制基础类型,请使用 enum-base 语法(例如A),并查询它,您可以使用enum A : char特征。

如果您真的希望在定义中看到枚举器类型的效果,可以尝试这样的事情:

std::underlying_type

答案 3 :(得分:4)

没有。自ANSI C以来,符合编译器的用户经常使用int存储枚举,即使所有值都很小。

在你说这是疯了之前它应该使用最小的类型(如果你使用__attribute__((packed))就像GCC那样),考虑一下ABI的兼容性。如果您发布使用枚举类型的库,则您希望该类型的大小不会更改。如果所有枚举都以4个字节开始,则增加的可能性就是只需重新链接更新的库就可以了。