Pity the (wo)man who does not use -Wall -Wextra for (s)he is truly mistaken
https://www.godbolt.org/z/99ejvY9Pc
It requires the separate option -Wimplicit-fallthrough:
https://www.godbolt.org/z/GP576zG9h
(which tbh sounds like a bug, because usually Clang tries to emulate GCC behaviour)
https://en.cppreference.com/w/cpp/language/attributes/fallth...
(For backwards compatibility, it still must fallthrough with or without the attribute; the attribute just signals programmer intention and silences the warning.)
-Wimplicit-fallthrough
From the compiler docs. It's just not a problem. If you waste time once and learn about warning options in the compiler you will be better off anyway.
It's like with assignment being an expression panic - something that maybe bites you once and then you learn to read the compiler warnings and it never causes problems again.
If you don't want to read then there is: -Werror
Available.GCC has a warning in the '-Wextra' warning set, Clang requires the explicit option `-Wimplicit-fallthrough', MSVC is completely silent (apparently it's in the CppCoreCheck rules though).
This should really be in the default warning set with an annotation that the fallthrough is intended (unless the case-branch is completely empty).
This was (almost certainly) done to simplify the compiler. CASE in C is not actually a structured control construct despite its syntactic appearance, it's just a computed GOTO. This is what makes things like Duff's device [1] possible.
My mental picture of what C-compilers are up to turned out to be a lot more sophisticated than reality.
But having written a few Forth-interpreters, it makes total sense to me. Treating the input as a mostly unstructured stream of tokens is very convenient.
Choices/options for the same result, tend to make code less readable.
case 1:
case 2:
... code ...
the fallthrough is allowed. case 1:
... code ...
case 2:
... code ...
Is an error. But `goto case` can be used: case 1:
... code ...
goto case;
case 2:
... code ...
which makes it clear. No new keywords are needed. C could adopt this easily.
The worst offender is the quasi-obligatory "break" statement in "case" blocks. Fall-through cases are useful for things like lexers but probably not needed in 99.999% of other programs. I wonder how many millions of (wo)man hours have been wasted on debugging missing breaks. (yes, I know that linters exist)