当C ++中的switch语句中没有处理所有枚举值时,编译时断言


Compile-time assert when not all enum values are handled in a switch statement in C++

当不是在switch语句中处理所有可能的枚举值时,我想得到编译器警告或错误。 当然,我可以添加一个带有断言的默认情况,并且(最终)在运行时获得错误。 但是我想在编译时遇到错误。

我不确定这是否可能与C ++有关,但也许有人知道一个技巧......

编辑:
使用-Wswitch似乎是GCC的解决方案。 VS2010有类似的东西吗? (我没有使用GCC)。

EDIT2:
好的,我找到了VC ++(VS2010)的解决方案:

启用警告C4062会在缺少值时发出警告,并且不提供默认情况。

即使提供了默认情况,启用警告C4061也会在缺少值时发出警告。


您还没有提到您正在使用的编译器。如果您正在使用GCC,只需启用-Wswitch(由-Wall自动启用)即可免费获得。


AFAIK没有传统的方法来实现你想要的MSVC。有类似的事情,但它们涉及复杂的模板伏都教或真正凶猛的宏谜语。

例如,不要以常规方式定义枚举,而是执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
#define MyEnumEntries(m) \
    m(A, 1) \
    m(B, 2) \
    m(C, 3) \

enum Abc {

    // the following will expand into your enum values definitions
#   define M_Decl(name, value) name = value,
    MyEnumEntries(M_Decl)
};

现在,您的交换机可以重写为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Abc a = A;

switch( a )
{
#define M_Goto(name, value) \
case value:

    goto label_##name;

MyEnumEntries(M_Goto)


case label_A:
    // TODO
    break;
case label_B:
    // TODO
    break;
}

如果您不为所有枚举值添加开关条目label_...,则上述将无法编译。


如果您使用g ++,使用-Wall,那么您将获得它。

例如,这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
enum Abc
{
  A =1,
  B,
  C
};

Abc a = A;
switch( a )
{
 case A:
  break;
 case B:
  break;
}

会引起警告。

但最好使用default断言失败的情况,因为当你添加一个新的枚举值时,你必须改变你在这个枚举上使用开关的所有文件。


如果您使用-Wall启用所有警告,g ++会自动执行此操作。