https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87951
--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Vitali from comment #5) > Jonathan, I think the defect report here does actually apply to this > example. I didn't say otherwise. > I agree the argument could be made that if there's gaps in the enum > values that it's arguable that the current GCC behaviour is standards > compliant (clearly clang & GCC disagree on this for both C & C++ so unclear > who's right or wrong in their interpretation of what's allowed). No, it has nothing to do with "gaps" in the enum. This is a myth. All that matters is the range of representable values, which (for an enumeration without a fixed underlying type) depends on the number of bits required to represent the minimum and maximum enumerator values. It doesn't make any difference whatsoever whether there are "gaps" between those minimum and maximum values. > However, in the example posted this is a "dense" enum. What matters is that all the values of the enum can be represented in a single bit, and so the only valid values are 0 and 1, which happen to have enumerators. But the only valid values would still be 0 and 1 if your enum was defined as enum Enum { B=1 }; and so a switch that failed to handle the possibility of Enum(0) would be wrong (even with -fstrict-enums) The mental model of "dense" vs "gaps" is WRONG. > There's no integer > value possible that's not outside the range & yet GCC still continues to > treat that as a possibility & thus missing optimization opportunities & > generating false-positive warnings. Yes, that's what -fstrict-enums is for. The default (without -fstrict-enums) assumes most code is buggy and doesn't follow the rules. If you do not use values outside the valid range of values for the enumeration, use -fstrict-enums. I can see some value in the suggestion to annotate a specific enumeration type as strict, but that might not be the right solution. What matters is how the enumeration type is used (whether invalid values are ever created) and that isn't something you can guarantee when the enum is declared. You *can* annotate the uses of a specific enum, but telling the compiler that no other values will ever be used in the switch, by adding: default: __builtin_unreachable();