c - C中枚举器列表中枚举常量的类型

标签 c enums embedded keil

已编辑

我目前正在开发一个多平台枚举解析器,在尝试回答上述问题时发现了这种奇怪的行为。

问题 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/

相关文章:

c - 如何在C中解决这个问题?

c++ - 如何将焦点重新集中在透明(启用点击)窗口上

java - Thread 的 run() 方法中的最终枚举

ruby-on-rails - 如何动态获取枚举的字符串值?

c++ - 如何解释 C++ 中的二进制数据?

c - USART嵌入C.触发字符存储数组

c - 我将如何写入内存?

c - 如何测试我自己的(小型)嵌入式操作系统的可靠性?

c - 如何用 char 初始化矩阵。我正在尝试做公鸡游戏,一开始我需要一个 3x3 的矩阵,其中 "-"

entity-framework - Entity Framework 5 和字符枚举