为什么C编译器没有检查枚举?

Ant*_*t's 8 c compiler-construction enums

以下文字摘自C语言创作者编写的C编程语言第2版(所以我认为它是正确的):

虽然可以声明枚举类型的变量,但编译器不需要检查存储在这样的变量中的是枚举的有效值.

我有些疑惑:

  1. 对于C语言中的哪些情况,编译器检查的值是enum什么?
  2. enum由于某种原因,不检查常量.为什么不?原因是什么?
  3. 既然enum未经编译器检查,是否使用enum容易出错?请解释.

Nic*_*son 8

  1. 枚举就像一个花哨的整数,并且它比定义整个加载的常量或预处理器宏作为你想要存储的常量值的名称更好,因为编译器(或编辑器)可以检查你是否正在使用正确的名称和使用正确类型的值.另一方面,只是一个int,没有什么可以阻止你输入一个你没有命名的值,这偶尔会有用.

  2. 在每种情况下都无法检查它们.如果将两个数字相加以获得将放入枚举类型变量中的值,该怎么办?它可以是在运行时生成的任何值,因此无法检查(至少没有大量开销).

  3. C中的一切都是不安全的; 几乎没有编译器可以完全阻止你滥用的功能.枚举是安全的,因为它们可以有效地防止程序员错误和混乱,而不是因为它们阻止你做一些愚蠢的事情.


pmg*_*pmg 6

你可以做类似的枚举

enum status {
    ST_READY = 1 << 0, /*  1 */
    ST_WAIT  = 1 << 1, /*  2 */
    ST_ERROR = 1 << 2, /*  4 */
    ST_HALT  = 1 << 3, /*  8 */
    ST_ETC   = 1 << 4, /* 16 */
};
Run Code Online (Sandbox Code Playgroud)

然后定义该类型的对象

enum status status;
Run Code Online (Sandbox Code Playgroud)

并将其设置为某些"简单"状态的按位OR

status = ST_WAIT | ST_ERROR; /* recoverable error */
Run Code Online (Sandbox Code Playgroud)

请注意,该值ST_WAIT | ST_ERROR6该值并不是枚举的一部分.


回答你的问题:

  1. C编译器让程序员自己在脚下射击.
  2. C编译器让程序员自己在脚下射击.
  3. C编译器让程序员自己在脚下射击.