不管枚举值的数量,常量枚举大小

ana*_*and 12 c c++ enums

enum无论类型中的枚举数是多少,为什么总是2或4个字节(分别在16位或32位架构上)的大小?

编译器是否enum像它那样对待union

Kei*_*son 20

在C和C++中,enum类型的大小是实现定义的,并且与某个整数类型的大小相同.

一种常见的方法是使所有enum类型的大小相同int,因为这通常是实现最有效访问的类型.例如,将其设为单个字节可以节省非常小的空间,但可能需要更大更慢的代码来访问它,具体取决于CPU架构.

在C中,枚举常量是按类型定义的int.所以给出:

enum foo { zero, one, two };
enum foo obj;
Run Code Online (Sandbox Code Playgroud)

表达式zero是类型int,但是obj类型enum foo,可能具有或不具有相同的大小int.假设常量是类型int,则枚举类型的大小往往更容易.

在C++中,规则是不同的; 常量是枚举类型.但同样,出于效率原因,每种enum类型通常最有意义的是一个"单词",通常是大小int.

2011 ISO C++标准添加了为类型指定基础整数类型的功能enum.例如,您现在可以写:

enum foo: unsigned char { zero, one, two };
Run Code Online (Sandbox Code Playgroud)

这保证了两者的类型foo和常数zero,onetwo具有1个字节的大小.C没有此功能,并且2011年以前的C++编译器不支持它(除非它们将其作为语言扩展提供).

(接下来是.)

那么如果你的枚举常数太大而无法适应int呢?您不需要2 31或甚至2 15个不同的常量来执行此操作:

#include <limits.h>
enum huge { big = INT_MAX, bigger };
Run Code Online (Sandbox Code Playgroud)

bigis 的值INT_MAX通常为2 31 -1,但可以小到2 15 -1(32767).bigger隐含的价值big + 1.

在C++中,这没关系; 编译器只会选择一个huge足够大的基础类型来保存该值INT_MAX + 1.(假设存在这样的类型;如果int是64位并且没有比这更大的整数类型,那将是不可能的.)

在C中,由于枚举常量是类型int,因此上述内容无效.它违反了N1570 6.7.2.2p2中规定的约束:

定义枚举常量值的表达式应为整数常量表达式,其值可表示为 int.

所以编译器必须拒绝它,或至少警告它.例如,gcc说:

错误:枚举值溢出


Bar*_*mar 9

枚举不是一种结构,它只是一种给一组整数赋值的方法.具有此类型的变量的大小只是基础整数类型的大小.


Ada*_*eld 8

枚举的大小是实现定义的 - 允许编译器选择它想要的任何大小,只要它足够大以适应所有值.一些编译器选择对所有枚举类型使用4字节枚举,而一些编译器将选择可以符合枚举值的最小类型(例如,1,2或4个字节).C和C++语言标准允许这两种行为.

从C99§6.7.2.2/ 4:

每个枚举类型应与char有符号整数类型或无符号整数类型兼容.类型的选择是实现定义的,110)但应能够表示枚举的所有成员的值.

来自C++03§7.2/ 5:

枚举的基础类型是一个整数类型,可以表示枚举中定义的所有枚举器值.它是实现定义的,其中整数类型用作枚举的基础类型,除了基础类型不应大于int枚举器的值不能适合于intunsigned int.如果枚举列表为空,则基本类型是因为如果枚举具有值为0的值的单个枚举sizeof()施加到枚举类型,枚举类型的对象,或枚举,是的值sizeof()施加到基础类型.

  • @PHIfounder:C也不一定如此.在C和C++中,`enum`类型的基础整数类型是实现定义的; 它可以是`char`或`unsigned char`,只要所有常量都可以在该类型中表示.C枚举*常量*的类型为`int`,但类型本身不是. (4认同)