枚举类应该是强枚举,因为它们不会隐式地与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
在开关中触发警告。
答案 0 :(得分:1)
您可以返回一个虚拟变量,以删除“控制到达非void函数的末尾”。这样,警告将被删除,并且对enum-class的任何添加仍将在switch语句中触发警告:
int sw(EC ec) {
switch (ec) {
case EC::a: return 0;
case EC::b: return 1;
}
return 0; //dummy variable
}
答案 1 :(得分:1)
“控制到达非空函数的末尾”与常见的“在开关[-Wswitch]中未处理的枚举值'c'”警告完全不同。我认为编译器在此过于谨慎,但此警告似乎很方便,因为它将防止由于修改enum
并忽略-Wswitch
警告而引起的潜在未来UB。
以这种方式重写此代码段将使代码成为将来的证明:
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
}
答案 2 :(得分:0)
一个enum
变量-老一和enum class
都可以容纳不是枚举成员之一的值。只要整数值适合基础类型(还有更多限制),将其存储在枚举类型中是有效的。
答案 3 :(得分:0)
这对我有用:
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;
}
答案 4 :(得分:0)
在GCC / Clang / ICC中,您可以使用__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)
。