枚举类应该是强枚举类,因为它们不会隐含地转换到和从 int
. 比如说,。
enum class EC { a, b };
然而,当切换到这样一个 "强枚举 "时,
int sw(EC ec) {
switch (ec) {
case EC::a: return 0;
case EC::b: return 1;
}
}
gcc -Wreturn-type
-要我加一个 default
子句到开关,即使所有合法的枚举值都被覆盖。
warning: control reaches end of non-void function [-Wreturn-type]
在一个旧的(非类)枚举中,这是有意义的,因为所有的 int
可能被意外地转换成了 EC
. 但我(显然是错误的)认为将一个无效的枚举成员分配给一个枚举类是UB。
我怎样才能使用真正强大的枚举类,让编译器意识到类似于 sw
覆盖所有可能的路径?当然,我可以直接添加一个 default:
分支,我知道它永远不会被触发,但我。想确保增加成员到 EC
以后 会 报警.
你可以返回一个虚变量,以消除 "控制达到非void函数结束 "的警告。这样一来,警告就被删除了,任何对枚举类的添加仍然会在切换语句中触发警告。
int sw(EC ec) {
switch (ec) {
case EC::a: return 0;
case EC::b: return 1;
}
return 0; //dummy variable
}
"control reaches end of non-void function "和常见的 "enumeration value 'c' not handled in switch [-Wswitch]"警告是完全不同的。我认为编译器在这里有点过于谨慎,但这个警告可能会很方便,因为它将防止未来因修改 enum
漠视 -Wswitch
警告.
像这样重写这个片段,会使代码具有未来性。
enum class EC { a, b /*,c */ };
int sw(EC ec) {
int result{};
switch (ec) { // warning: enumeration value 'c' not handled in switch [-Wswitch]
case EC::a: result = 0; break;
case EC::b: result = 1; break;
}
return result; // control flow will always leave function properly
}
A enum
变量--包括老式的和 enum class
可以存放不属于枚举成员的值。只要整数值符合底层类型(还有一些限制),就可以将其存储在枚举类型中。
这对我来说是有效的。
enum class EC {a, b, c};
int sw (EC ec)
{
int rc;
switch (ec)
{
case EC::a:
rc = 0;
break;
case EC::b:
rc = 1;
break;
}
return rc;
}
在GCCClangICC中,你可以用下面的命令来关闭这个警告 __builtin_unreachable()
:
int sw(EC ec) {
switch (ec) {
case EC::a: return 0;
case EC::b: return 1;
}
assert(false);
__builtin_unreachable();
}
在MSVC __assume(0)
可以使用。