120120从当前的C标准(C99)中获取:http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
6.7.2.2枚举说明符
[...]
约束
定义枚举常量值的表达式应该是一个整数常量表达式,其值可以表示为int。
[...]
每个枚举类型应与char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,但必须能够表示枚举的所有成员的值。
请注意,编译器并不总是遵循标准,但本质上:如果您的枚举除int以外的任何类型,那么您在深度“不受支持的行为”领域,这可能会在一两年后回来咬您。
更新:最新公开可用的C标准草案(C11):http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf 包含相同的条款。因此,本答案对于C11仍然有效。- Michael Stum73只有这些,我想以下内容是有效的:枚举 { LAST = INT_MAX,LAST1,LAST2 }; 因此,LAST2在int中无法表示,但没有定义它的表达式。 - Johannes Schaub - litb4在实际的PDF文档中,它定义道:"枚举列表中的标识符被声明为具有int类型的常量[...]"。我省略了这部分以使语言不太啰嗦。 - Michael Stum3注意:“a signed integer type, or an unsigned integer type”。这不一定是 int。short 和 long 也是整数类型,并且无论实现选择什么,所有值都必须适合(“shall be capable of representing the values of all the members of the enumeration”)。 - user82442510值得注意的是:枚举常量和枚举类型并不是同一回事。前者是枚举声明列表中的内容,而后者是实际的变量。因此,虽然枚举常量必须为“int”类型,但实际的枚举变量可以是其他类型。这是标准中公认的不一致之处。 - Lundin5为了澄清Lundin的观点:对于enum my_enum { my_value },my_value将具有类型int,但是enum my_enum可以具有实现定义的类型,该类型必须至少表示所有枚举值。因此,my_value可能会被截断转换为enum my_enum,但保证不会溢出。 - P O'Conbhui显示剩余2条评论回答链接111111enum只保证足够容纳int值,编译器可以根据定义的枚举常量自由选择实际使用的类型,因此如果可以表示您定义的值,它可能会选择更小的类型。如果需要枚举常量无法适应int类型,就需要使用特定于编译器的扩展来实现。
- Robert Gamble614根据@MichaelStum的回答,你的第一句话应该是“枚举类型只能保证适合于int值”,这与你最后一句话似乎有冲突。请澄清一个限制条件,是枚举类型应该比int大还是比int小? - HaskellElephant作为对二进制补码平台(这是现在所有系统吗?)的一种丑陋的实现敏感的黑客技巧,您可以通过确保枚举包含负值来强制使枚举与int一样大。虽然不推荐使用此技术。 - persiflage7这个回答似乎暗示枚举类型的大小与“int”类型一样大。参考了C99标准的Michael Stum的回答表明,枚举类型的大小可能只有一个“char”类型那么小。 - Frank Kusters3这个回答的第一句话是不正确的。 枚举 只保证足够大,能够容纳枚举中最大枚举值的数值。 - M.M@M.M,他的意思是要保存最大的int值。这是正确的陈述。你的陈述实际上是不正确的。如果枚举器比int大,那么enum将无法保存最大的枚举器。我通过将我的64位枚举器截断为最大的int(在我的情况下是32位)来学习到了这一点。 - SO_fix_the_vote_sorting_bug在标准 C 中,@jdk1.0 所有的枚举器都具有 int 类型。您所描述的行为是编译器特定的扩展。 - M.M回答链接2424虽然之前的答案是正确的,但有些编译器有选项来打破标准并使用最小的类型来包含所有值。
例如,在GCC中(文档在GCC手册中),可以这样实现:
enum ord {
FIRST = 1,
SECOND,
THIRD
} __attribute__ ((__packed__));
STATIC_ASSERT( sizeof(enum ord) == 1 )
- Kevin Cox215据我所见,实际上这并不违反标准。正如Michael Stum的回答中所解释的那样,只要所有值都适合,标准允许编译器选择枚举的实际类型。 - sleske2我曾经使用过 macOS 的 C++ 编译器,它利用枚举类型值范围有限的特点将它们存储在更小的类型中。我不记得是 Metrowerks Codewarrior 还是 XCode。这符合 C++ 标准。通常情况下不能假设 sizeof(MyEnum) == sizeof(int)。 - persiflage回答链接00只需将枚举的最后一个值设置为足够大的值,使其成为您想要的枚举大小即可:
enum value{a=0,b,c,d,e,f,g,h,i,j,l,m,n,last=0xFFFFFFFFFFFFFFFF};
- scirdan33虽然这段代码可能能够回答问题,但是提供关于它如何以及/或者为什么解决了问题的额外背景信息可以提高答案的长期价值。 - leopal1这是错误的。使用gcc 8.4.0编译您的示例:sizeof(a)为4,sizeof(last)为8。 - Mateo de Mayo2typedef enum {a1=0,b1,c1,d1,f1,last1=0xFFFFFFFFFFFFFFFF} testing1;
typedef enum {a2=0,b2,c2,d2,f2,last2=0xFFFFFFFF} testing2;
类型为testing1的变量大小为8,类型为testing2的变量大小为4。 - scirdan回答链接-1-1我们对enum变量的大小没有控制权。 它完全取决于实现,编译器提供了使用enum来存储整数名称的选项,所以enum遵循整数的大小。
- MIke回答链接-2-2在C语言中,enum保证大小与int相同。有一个编译时选项(-fshort-enums)可以将其缩短(这主要适用于值不超过64K的情况)。没有编译时选项可以将其大小增加到64位。
- rashok1不是简短,有时更短。 - rsaxvc回答链接-11-11考虑以下代码:
enum value{a,b,c,d,e,f,g,h,i,j,l,m,n};
value s;
cout << sizeof(s) << endl;
它将输出4。因此,无论enum包含多少个元素,其大小始终是固定的。
- tushan37Michael Stum的回答是正确的。这与编译器有关。您可以使用IAR EWARM自行尝试。IAR EWARM显示您的示例为1。如果有多达255个项,它仍会显示为1。在添加第256个项目后,它会增加到2。 - desowin16问题并不涉及 C++。 - Michas8在写任何C或C++代码之前,需要注意的重要事情:仅仅因为它编译通过并不意味着它符合标准。仅仅因为你得到了特定的结果,并不意味着标准规定你总是会得到那个结果或其他用户运行你的代码时也会得到同样的结果。像这样的问题需要回答参考标准或至少给定编译器/ABI的实现定义规范。仅编译和运行程序,并在某一天看到一个结果,并没有传达任何关于这些问题的教训(以及很少关于其他任何事情)。 - underscore_d回答链接