避免误报-Wswitch警告

1ac*_*ace 8 c enums

我们有一个值列表(foo.lst):

foo,
bar,
baz,
Run Code Online (Sandbox Code Playgroud)

让我们从中得到一个枚举

enum foo {
  #include "foo.lst"
  _foo_length
};
Run Code Online (Sandbox Code Playgroud)

让我们使用枚举switch:

int main(void) {
  enum foo[_foo_length];

  switch(f[0]) {
    case foo: return 0;
    case bar: return 0;
    case baz: return 0;
  }

  __builtin_unreachable();
}
Run Code Online (Sandbox Code Playgroud)

(这段代码很愚蠢,但只是忽略它)

问题:
随着-Wswitch(包括在内-Wall),GCC和Clang(可能还有其他人)会发出警告:

警告:在switch [-Wswitch]中未处理枚举值'_foo_length'

解决方案:

  • 禁用-Wno-switch隐藏警告.
    缺点:我们失去了关于case交换机中任何其他缺失的警告.
  • 添加default: unreachable();案例.
    缺点:我们丢失了丢失案例的编译时警告,如果我们在调试时碰到其中一个丢失的案例,则支持运行时崩溃.
  • 用a替换枚举的最后一个值#define _foo_length (baz + 1),使其不再是枚举的一部分.
    缺点:它要求每次将值添加到列表时手动更新定义.有人会忘记,打破一切.

理想情况下,应该有一种方法可以将枚举值标记为不可赋值,从而使得在读取可能的值时不会在编译器中产生警告,并且不存在此值,而不需要预处理器宏需要重复修改.

有什么相似的吗?我没有想到的任何其他选择?

Bar*_*mar 3

使用

case _foo_length:
    unreachable();
    break;
Run Code Online (Sandbox Code Playgroud)

以便所有案件都能得到处理。您可以为它创建一个宏,以防止它变得如此冗长。