看一下下面的代码:
typedef enum {
A, B, C
} Foo;
int foo(Foo x) {
switch(x) {
case A: return 1;
case B: return 2;
case C: return 3;
}
}
GCC 10.2 输出
<source>:11:1: warning: control reaches end of non-void function [-Wreturn-type]
11 | }
| ^
这是因为我可以向
foo
传递像 42 这样的东西,而不仅仅是 A
、B
或 C
。所以问题是:如何告诉 GCC 只有 A
、B
或 C
可以被 switch 语句处理,否则行为是未定义的?接受编译器特定的功能。让我指出一些不满足我的解决方案。首先,我可以插入
default: __builtin_unreachable();
,但这会穿透 case 分析:想象一下,显然我正在添加 D
变量,而编译器不会告诉我 D
是未处理的。其次,我可以在 switch 语句之前插入
if (x > C) { __builtin_unreachable(); }
,但这太不可能了,因为 switch(x)
实际上是由一个宏生成的,这个宏不知道 Foo
的变量,它只知道一些变量 x
。
第三,我可以插入#pragma GCC diagnostic ignored "-Wreturn-type"
,但是由于switch(x)
是由宏生成的,这就是为什么我不能通过#pragma GCC diagnostic pop
将诊断恢复到先前状态的原因。
第四,我可以使用数组代替switch
,但返回的表达式不是常量,而是由生成switch(x)
的宏的用户提供的。
最后一个:在switch语句之后,我可以编写return 42;
,但是我再次想自动禁用生成switch(x)
的宏内部的警告,因为它在我的代码库中被广泛使用。
default:
情况吗? - Code-Apprentice