此枚举声明是否符合标准?

时间:2015-10-25 22:19:48

标签: c++ c enums

因此,通常枚举用于将“常量整数”组声明为另一种类型,代表某种东西。例如

enum Color {RED=0, BLUE, YELLOW};

这很清楚。但最近我在代码中遇到了以下内容。这是嵌入式系统的编译器。

enum State {DISABLED=0, ENABLED=!DISABLED};

它运作得很好。它表现为布尔类型。我的问题是,它(这种语法)是否符合ANSI标准?

如果它符合标准,那么为什么编译器会在内部定义像_Bool这样的布尔表示,然后在stdbool.h(对于C语言)它们执行:

#define bool _Bool
... // here goes definitions of true and false

而不是

enum bool {false=0, true=!false};

哪个更干净?

3 个答案:

答案 0 :(得分:6)

是的,这是符合标准的。

!DISABLED是一个有效的常量表达式,这是enum值所需的全部内容。

enum State {DISABLED=0, ENABLED= (!DISABLED)};
//                               ^^^^^^^^^^^

在引用DISABLED的位置,编译器知道它的值,因此它可以计算从它派生的表达式的值,即!DISABLED。这是写ENABLED=1的一种奇特方式。

答案 1 :(得分:3)

根据C标准(6.2.1标识符范围)

  

每个枚举常量的范围都在...之后开始   枚举器列表中定义枚举器的外观

同样在C ++中有效(3.3.2声明点)

  

5普查员的声明点紧随其后   枚举器定义。[例如:

const int x = 12;
{ enum { x = x }; }
  

这里,枚举器x用常量的值初始化   x,即12.-末端示例]

因此,您可以在枚举中的下一个枚举数的定义中使用已定义的枚举器。

对于C类型_Bool,它出现在C 99中。在此标准之前,在C中使用了显式常量或枚举。

定义像这样的枚举是没有意义的

enum bool {false=0, true!=false};

因为类型_Bool已经有两个值0和1。

答案 2 :(得分:3)

是的,声明在C和C ++中完全有效且可移植。

在C和C ++中,这个:

enum State {DISABLED=0, ENABLED=!DISABLED};

完全等同于:

enum State {DISABLED=0, ENABLED=1};

以及:

enum State {DISABLED, ENABLED};

但出于不同的原因。

在C中,一元!运算符生成类型为int的结果,其值为0(如果操作数不等于0)或{{ 1}}(如果操作数等于1)。 0相当于!x。 (当用作条件时,任何非零值都被视为true,但x == 0!运算符总是产生==0的结果。)枚举常量始终为1类型;如果指定了值,则在必要时将其转换为int

(C在1999标准中添加了类型int,但所有逻辑上产生" boolean"值的运算符仍然会产生_Bool类型的结果。)

在C ++中,一元int运算符的结果是!类型。结果为boolfalse,其中C true运算符将分别产生!0。与在C中一样,如果指定了值,则根据需要进行转换; 1boolfalse分别转换为true0

在C中,枚举常量始终为1类型。在C ++中,它们是枚举类型,在本例中为int

在同一类型声明中引用较早的枚举常量是合法的。在声明之后,每个枚举常量都会变得可见。

至于:

enum State

更清晰
enum bool { false = 0, true = !false );

(在C中;它在C ++中是非法的),我恭敬地不同意。对于熟悉C的人来说,常量enum bool { false = 0, true = 1 }; 是完全清楚的。将其重写为1是没有用的。事实上,当!false不可用时(这些日子很少见),我已经使用过:

<stdbool.h>

typedef enum { false, true } bool; false将被赋予正确的值这一事实恕我直言。

至于为什么C99没有像这样使用true定义,我怀疑它是因为每个枚举类型都与某些实现定义的整数类型兼容。 (对于gcc,它通常是enumunsigned int。)委员会希望int是一个转换级别低于任何其他整数类型的不同类型。 (并且他们无法在不破坏现有代码的情况下使_Bool成为关键字。)