Let's have a list of values (foo.lst):
foo,
bar,
baz,
Let's make an enum out of this
enum foo {
#include "foo.lst"
_foo_length
};
Let's use that enum in a switch:
int main(void) {
enum foo[_foo_length];
switch(f[0]) {
case foo: return 0;
case bar: return 0;
case baz: return 0;
}
__builtin_unreachable();
}
(this code is dumb, but just ignore that)
The problem:
With -Wswitch (included in -Wall), GCC and Clang (and probably others) will warn:
warning: enumeration value '_foo_length' not handled in switch [-Wswitch]
Solutions:
- Disabling
-Wno-switchhides that warning.
Downside: we lose warnings about any othercasemissing from the switch. - Adding a
default: unreachable();case.
Downside: we lose compile-time warnings of missing cases, in favour of a runtime crash if we ever hit one of the missing cases when debugging. - Replacing the last value of the enum with a
#define _foo_length (baz + 1), making it not part of the enum anymore.
Downside: it requires that define to be manually updated every time a value is added to the list. Someone will invariably forget, breaking everything.
Ideally, there should be a way to mark an enum's value as no being assignable, thereby making it not produce a warning in the compiler when reading the possible values and this one isn't there, without requiring a preprocessor macro needing duplicate modifications.
Is there anything like that? Any other option I didn't think of?