I have been programming in C for something like 20 years, and I don’t consider myself as illiterate in coding. But time to time, I still discover little gems and curiosities, even in the very deep roots of the C language.
The latest gem was this code snippet:
1 2 3 4 5 6 7
No, there’s no mistake – there’s a
while interleaved between
The fact is that
switch is actually a disguised dispatch of
goto (horror!) equivalent instructions, and
case a disguised label case. As you can jump from/to nested loops or conditions, the code is perfectly valid (and logical).
The above code can be rewritten as something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
This was confirmed by the specialists of
comp.lang.c, with interesting remarks:
- This coding technic is actually pretty classic in highly-optimized code (shame on me), and called Duff’s device, and allows, for example, to copy blocs of memory in a single row, inside a reduced loop, rather than copying the remainder outside the loop, and copying full chunks inside it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
- You may end up with the same issues as for the
gotoequivalent ; such as uninitialized variables: (note that clang detect this case, but not my version of gcc)
1 2 3 4 5 6 7 8
There’s one constraint you have to follow (please take your breath before reading): “If a switch statement has an associated case or default label within the scope of an identifier with a variably modified type, the entire switch statement shall be within the scope of that identifier.”. Basically, it means that if you are foolish enough to use this coding style, AND foolish enough to use variable-length-variables (such as dynamic arrays), then the compiler has the right to put a contract on you.
Abuse of interleaving of switch/case and other constructs may turn your code into a steaming pile of crap. Did I tell you that
casewas somewhat equivalent to
TL;DR: take an aspirin and good nite.