I recently discovered that switch (...) while (0) {}
is legal in C (here), but I cannot find an explanation about this thing.
The only other time I saw this in the Internet is in an obfuscation GitHub repository, without any explanation.
All my researches obviously gave me results about while or switch loops, without even mentioning this syntax, so I guess it's more something legal but very rare and likely useless, an abuse of the standard. Can anyone help me understand this ?
EDIT : As explained in @phuclv answer, a switch statement expects a selection statement right after, which can be brackets with some code inside (in this case... likely case statements) or a loop with its own brackets etc, it means this is legal in C :
switch (...) while (...) switch (...) {}
switch
doesn't care at all about what statement follows, it only seems to look for case(s) and / or default.
switch (1) while (0) {
puts("Not executed");
}
The puts
statement isn't executed because there's no case / default, so the switch is basically useless here.
You can see it on Compiler Explorer, GCC gives a warning and removed the switch.
However, beware :
#include <stdio.h>
int main(void) {
switch (1) while (1) switch (0) {
case 1:
puts("hello");
}
}
Nothing is displayed and the program is exited instantly, because the switch (1) has no case 1 or default statement. If we add one :
switch (1) case 1: while (1) switch (0)
The program loops indefinitely because the most nested loop is switch (0) with no case 0 or default.
Conclusion : The while (0)
is only an abuse and has no utility except obfuscation, but that's still an interesting thing to know.
In the C standard a statement is defined as one of these
A.2.3 Statements
(6.8) statement:
labeled-statement compound-statement expression-statement selection-statement iteration-statement jump-statement
switch
is a selection-statement
which is defined to have syntax like this
(6.8.4) selection-statement:
if ( expression ) statement if ( expression ) statement else statement switch ( expression ) statement
So switch
receives an expression
and do the statement
, which is normally the compound-statement
{}
but it can be any statement including the iteration-statement
(6.8.2) compound-statement:
{ block-item-listopt }(6.8.5) iteration-statement:
while ( expression ) statement do statement while ( expression ) ; for ( expressionopt ; expressionopt ; expressionopt ) statement for ( declaration expressionopt ; expressionopt ) statement
switch
statement jumps to the labeled-statement
(which is also a normal statement) and it doesn't care about the content inside the sub statement, the compiler will just generate a computed jump into the case
matching expression
(6.8.1) labeled-statement:
identifier : statement case constant-expression : statement default : statement
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With