根据§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)。
答案 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个字节开始,则增加的可能性就是只需重新链接更新的库就可以了。