已编辑
我目前正在开发一个多平台枚举解析器,在尝试回答上述问题时发现了这种奇怪的行为。
问题 A)
C标准是否在枚举声明完成之前确定枚举常量的类型?
以Keil ARMCC为例:
enum e {
VAL0 = (signed char)126,
VAL1,
VAL2,
SIZE0 = sizeof(VAL0),
SIZE1 = sizeof(VAL1),
SIZE2 = sizeof(VAL2)
};
我得到 SIZE0 = 1、SIZE1 = 1、SIZE2 = 8。 (如果我评估定义之外的枚举常量的大小,所有的大小都是 int)。
它们不应该都等于 sizeof( int ) 吗? (请记住,在本例中,int 的大小为 4 个字节。)
问题 B)
对于 Keil C251,我有以下内容:
signed int VALUE0 = (signed char)-1;
enum{ VALUE1 = (signed char)-1 };
enum{ VALUE2 = -1 };
printf( "Is VALUE0 equal to VALUE1? ---> %s", VALUE0 == VALUE1 ? "Yes!" : "No!" );
printf( "Is VALUE0 equal to VALUE2? ---> %s", VALUE0 == VALUE2 ? "Yes!" : "No!" );
打印:
Is VALUE0 equal to VALUE1? ---> No!
Is VALUE0 equal to VALUE2? ---> Yes!
不应该都打印 yes 吗?
我遗漏的 VALUE0 和 VALUE1 的定义之间是否存在差异,也许是类型转换?或者这可能是编译器错误?
最佳答案
在 C 中(与 C++ 不同),枚举常量是 int
类型。在类型声明结束之前引用枚举常量是合法的。
如果 Keil ARMCC 给你 sizeof(VAL0) != sizeof (int)
,其中 VAL0
是一个枚举常量,那么 Keil ARMCC 不是一个符合规范的 C 编译器.我在这里看到其他表明它不合格的问题。
不符合规范不一定是编译器错误(除非供应商声称它符合规范,但据我所知他们没有)。
关于 B 部分:
enum e{
MIN_SIGNED_CHAR_0 = (signed char)( -128 ),
MIN_SIGNED_CHAR_1 = -128,
MIN_SIGNED_CHAR_2 = ( signed int)(signed char)( -128 ),
MIN_SIGNED_CHAR_3 = (unsigned int)(signed char)( -128 ),
MIN_SIGNED_CHAR_0_PLUS_1 = MIN_SIGNED_CHAR_0 + 1,
MIN_SIGNED_CHAR_1_PLUS_1 = MIN_SIGNED_CHAR_1 + 1,
MIN_SIGNED_CHAR_2_PLUS_1 = MIN_SIGNED_CHAR_2 + 1,
MIN_SIGNED_CHAR_3_PLUS_1 = MIN_SIGNED_CHAR_3 + 1,
};
几乎所有符合规范的 C 编译器都应该为 MIN_SIGNED_CHAR_{0,1,2}
常量赋予值 -128
(int
类型) ,MIN_SIGNED_CHAR_{0,1,2}_PLUS_1
常量值为 -127
(也是 int
类型)。唯一可能的回旋余地是使用 SCHAR_MIN == -127
的实现,这是可能的但不太可能,而且显然 不是 Keil 编译器的情况.如果您得到不同的结果,要么是编译器中的错误。
但是 MIN_SIGNED_CHAR_3
的定义是有问题的。 int
值 -128
被转换为 signed char
,这不会更改值。然后将其转换为 unsigned int
,生成 UINT_MAX+1-128
(假设为 32 位,则为 4294967168
)。具有超出 int
范围的指定值的枚举常量是违反约束的,需要进行诊断。 (您收到编译时警告了吗?)如果编译器不拒绝该程序,结果是未定义的。
关于c - C中枚举器列表中枚举常量的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36781692/