C 枚举最后一个中的_BIG_ENUM=0xFFFFFFFF是什么意思?
我正在阅读一些代码,在枚举的最后一个值中发现了这个_BIG_ENUM=0xffffff。这一行的正确含义是什么。而且这个_BIG_ENUM没有在代码中的任何地方使用C 枚举最后一个中的_BIG_ENUM=0xFFFFFFFF是什么意思?,c,enums,C,Enums,我正在阅读一些代码,在枚举的最后一个值中发现了这个_BIG_ENUM=0xffffff。这一行的正确含义是什么。而且这个_BIG_ENUM没有在代码中的任何地方使用 #define CLS_COMM_CONFIG PORT_0,BAUD_9600,DATA_BIT_8,ONE_STOP,NO_FLOW_CONTROL #define PLS_COMM_CONFIG PORT_1,BAUD_115200,DATA_BIT_8,ONE_STOP,NO_FLOW_CONTROL typedef en
#define CLS_COMM_CONFIG PORT_0,BAUD_9600,DATA_BIT_8,ONE_STOP,NO_FLOW_CONTROL
#define PLS_COMM_CONFIG PORT_1,BAUD_115200,DATA_BIT_8,ONE_STOP,NO_FLOW_CONTROL
typedef enum _comm_config
{
_Zero=0,
PORT_0=_Zero,
BAUD_2400=_Zero,
NONE=_Zero,
HALF_STOP=_Zero,
DATA_BIT_5=_Zero,
NO_FLOW_CONTROL=_Zero,
_One = 1,
PORT_1=_One,
BAUD_4800=_One,
ODD=_One,
ONE_STOP=_One,
DATA_BIT_6=_One,
_Two=2,
PORT_2=_Two,
BAUD_9600=_Two,
EVEN=_Two,
TWO_STOP=_Two,
DATA_BIT_7=_Two,
_Three=3,
PORT_3=_Three,
BAUD_19200=_Three,
DATA_BIT_8=_Three,
_Four=5,
PORT_5=_Four,
BAUD_115200=_Four,
DATA_BIT_9=_Four,
_BIG_ENUM=0xFFFFFFFF,
}COMMConfig;
有些编译器可以将enum优化为更小的字长,但当并非所有代码都使用同一个编译器编译时,这可能会导致互操作性问题
如果为枚举分配了32位值,则会阻止此优化,强制将此枚举编码为32位整数。这没有任何意义,是一个错误 我想程序员不太了解枚举是如何工作的,并且认为他们可以通过将一个大整数常量赋给枚举常量之一来强制枚举变成32位。这是真的,但他们选择了一个坏值,它不会像他们认为的那样起作用 问题在于,虽然枚举变量可能具有实现定义的大小,但诸如
\u BIG\u ENUM
之类的枚举常量的类型始终为int
1)
但是0xFFFFFFFF
不适合32位int
所以这是一个bug。十六进制常量0xffffff
实际上是类型unsigned int
(假设为32位),它不适合,因此将有一个实现定义的从有符号到无符号的转换。这意味着我们在2的补码系统中得到值-1
。尽管gcc和clang具有严格的标准设置,但当枚举常量被指定为大于INT\u MAX
的整数常量时,它们甚至拒绝编译代码
当遇到值为-1
的枚举常量时,编译器可以为该类型的枚举变量(不一定是32位变量)选择任何带符号的类型2)
通过将代码更改为\u BIG\u ENUM=INT\u MAX,
(limits.h),可以修复代码。然后,枚举类型将变为int
或无符号int
1) C17 6.7.2.2/1 定义枚举常量值的表达式应为整数常量表达式,其值可表示为
int
2) C16.7.2.2/4
每个枚举类型应与char
、有符号整数类型或无符号整数类型兼容。类型选择由实现定义(128),但应能够表示枚举的所有成员的值
128)一个实现可能会延迟选择哪种整数类型,直到所有枚举常量都已完成
有人看见了
为什么有人否决了这一点?这是一个很好的答案,我怀疑它是正确的。这是错误的,因为0xFFFFFF不适合于枚举常量。枚举常量总是
int
,与枚举变量不同,不能得到不同的大小。@Lundin,为什么说0xFFFFFF不适合(32位)int
?@Lundin检查这个,这正是最后一句话。@Iharob Al-Asimi,这并不是Lundin不同意详细阅读的内容,尤其是1453 108)一个实现可能会延迟选择哪种整数类型,直到看到所有枚举常量。意味着编译器可以选择无符号int
。虽然我理解你的观点,但似乎有可能在某些编译器中,这个技巧工作得很好。但我们不知道这段代码是否用特定的编译器编译。@IharobAlAsimi不知道,因为枚举常量\u BIG\u ENUM
被赋值为-1.Re“但0xFFFFFF不适合32位整数”@Iharob Al-Asimi,您混淆了枚举的类型(灵活)和定义常量值的表达式的类型(不灵活)。@ikegami是的,原始代码将不会在gcc上以严格的设置编译,因为该错误。一旦发布了答案,请不要根本更改该问题。我回滚了你的更改。实际上,为什么问题标题说的是一件事,代码说的是另一件事。。。另请注意,\u BIG\u ENUM
是一个保留标识符,根据:“所有以下划线和大写字母或另一个下划线开头的标识符始终保留供任何使用。”作为保留标识符,其使用是不正确的。