C中的枚举的大小是多少?


140

我正在创建一组枚举值,但是我需要每个枚举值都是64位宽。如果我没记错的话,枚举的大小通常与int相同;但是我想我读过某个地方(至少在GCC中),编译器可以使枚举具有保持其值所需的任何宽度。那么,是否可能有一个64位宽的枚举?


1
因此,如果我很好理解,那么2 ^ 32枚举对您来说还不够吗?还是出于对阵的关注,我为什么很好奇为什么将这些值设为64而不是32?
2012年

1
@jokoon:老实说,我已经不记得了。我想我希望枚举包含大于2 ^ 32-1的值。
mipadi

一种用途是如果需要枚举和指针之间的联合。
Demi 2013年

Answers:


97

enum仅保证An 足够大以容纳int值。编译器可以根据定义的枚举常量自由选择使用的实际类型,因此,如果编译器可以表示您定义的值,则可以选择较小的类型。如果您需要不适合的枚举常量,int则需要使用特定于编译器的扩展名。


12
您的第一句话似乎与您的最后一句话冲突。是an enum应该大于int还是小于an的约束?在@MichaelStum回答之后,您的第一句话应该是“ enum仅保证将An 放入int值中”。
HaskellElephant 2014年

作为二进制补码平台上的丑陋的实现敏感型黑客(如今是否是所有系统?),您可以通过确保枚举包含负值来强制枚举与int一样大。虽然不是推荐的技术。
persiflage

7
这个答案似乎表明一个枚举与一个枚举一样大int迈克尔·斯托姆(Michael Stum)的答案引用了C99,他说一个枚举可能和一样小char
Frank Kusters

3
该答案的第一句话不正确。该enum只保证大足以容纳中枚举最大的枚举值。
MM

91

取自当前的C标准(C99):http : //www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

6.7.2.2枚举符
[...]
约束
定义枚举常数的值应是具有值的可表示为int的整数常量表达式的表达式。
[...]
每个枚举类型应与char,有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,但应能够代表枚举的所有成员的值。

并不是说编译器擅长遵循该标准,而是本质上:如果您的枚举不包含int,则您处于深层的“不受支持的行为,可能会在一两年之内让您陷入困境”。


3
仅此而已,我认为以下内容是有效的:枚举{LAST = INT_MAX,LAST1,LAST2}; 因此LAST2在int中无法表示,但是没有定义它的表达式。
Johannes Schaub-litb

4
在实际的PDF中,它定义为:“枚举数列表中的标识符声明为类型为int [...]的常量”。为了使它不太冗长,我省略了它。
Michael Stum

2
注意“ 一个有符号整数类型,或者一个无符号整数类型”。不一定intshort并且long也是整数类型,无论实现选择什么,所有值都必须适合(“ 能够代表枚举的所有成员的值”)。

3
值得注意:枚举常量枚举类型 不是一回事。前者是枚举声明列表的内容,后者是实际变量。因此,虽然枚举常量必须为int,但实际的枚举变量可以是另一种类型。这是标准中众所周知的不一致之处。
隆丁

1
为了阐明Lundin的观点:对于enum my_enum { my_value }my_value将具有type int,但是enum my_enum可以具有实现定义的类型,该类型必须至少表示所有枚举值。因此,my_value可能会缩小到的转换范围enum my_enum,但可以保证不会溢出。
P O'Conbhui

16

尽管前面的答案是正确的,但某些编译器可以选择打破标准并使用包含所有值的最小类型。

GCC的示例(《 GCC手册》中的文档):

enum ord {
    FIRST = 1,
    SECOND,
    THIRD
} __attribute__ ((__packed__));
STATIC_ASSERT( sizeof(enum ord) == 1 )

10
实际上,据我所知这并没有违反标准。如Michael Stum的答案所述,只要所有值都适合,该标准就允许编译器选择枚举的实际类型。
sleske 2015年

2
我使用过MacOS C ++编译器,它们确实利用枚举中有限的值范围将它们存储为较小的类型。不记得是Metrowerks Codewarrior还是XCode。这在C ++标准之内。通常,您不能假定sizeof(MyEnum)== sizeof(int)。
persiflage

0

只需将枚举的最后一个值设置为足够大的值,以使其达到您想要的枚举的大小,则该大小应为:

enum value{a=0,b,c,d,e,f,g,h,i,j,l,m,n,last=0xFFFFFFFFFFFFFFFF};

1
尽管此代码可以回答问题,但提供有关如何和/或为什么解决问题的其他上下文将提高​​答案的长期价值。

-1

我们无法控制enum变量的大小。它完全取决于实现,并且编译器提供了使用来存储整数名称的选项enum,因此enum遵循整数的大小。


-1

在C语言中,enum保证大小为int。有一个编译时间选项(-fshort-enums)可以使其更短(主要用于值不超过64K的情况)。没有编译时选项可以将其大小增加到64位。


-6

考虑以下代码:

enum value{a,b,c,d,e,f,g,h,i,j,l,m,n};
value s;
cout << sizeof(s) << endl;

它将给出4作为输出。因此,无论enum包含的元素数量如何,其大小始终是固定的。


6
迈克尔·斯托姆的答案是正确的。这是特定于编译器的。您可以使用IAR EWARM自己尝试一下。IAR EWARM在您的示例中显示1。如果有多达255项仍显1.将第256项之后,它上升到2
desowin

10
问题不在于C ++。
米查斯(Michas)'16

3
在编写更多C或C ++之前要实现的重要事项:仅仅因为编译即可,并不意味着它符合标准。仅仅因为您得到了给定的结果并不意味着Standard会说您将永远或其他用户在运行您的代码时会这样做。这样的问题需要一个答案,该答案引用给定编译器/ ABI 的标准或至少实现定义的规范。仅仅编译并运行一个程序,一天就可以看到一个结果,这对这些问题没有任何启示(而对其他任何问题则很少)。
underscore_d
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.