Take a look at the following code:
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 outputs
<source>:11:1: warning: control reaches end of non-void function [-Wreturn-type]
11 | }
| ^
This is because I can pass something like 42 to foo, not only A, B, or C. So the question is: how to tell GCC that only A, B, or C can be handled by the switch statement, otherwise the behavior is undefined? Compiler-specific functionality is acceptable.
Let me point some solutions that don't satisfy me. First, I could just insert default: __builtin_unreachable(); but this would penetrate case analysis: imagine that apparently I'm adding the D variant and the compiler would not tell me that D is unhandled.
Second, I could insert if (x > C) { __builtin_unreachable(); } before the switch statement, but this is too impossible because switch(x) is actually generated by a macro which doesn't know about the variants of Foo, it knows nothing but some variable x.
Third, I could insert #pragma GCC diagnostic ignored "-Wreturn-type", but again, switch(x) is generated by a macro and this is why I cannot revert the diagnostics to the previous state by #pragma GCC diagnostic pop.
Fourth, I could use an array instead of switch but the returned expressions are not constant and are provided by a user of the macro generating switch(x).
And the last one: I could write return 42; after the switch statement but again I want to disable the warning automatically inside the macro generating switch(x) because it's used extensively in my codebase.