Syntactically, the body of a switch is just a statement (usually, but not necessarily a compound statement)
6.8:
statement:
labeled-statement
compound-statement
expression-statement
selection-statement
iteration-statement
jump-statement
which may be labeled
6.8.1:
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
Example:
switch(1) one: case 1: dothis();
If it is a compound statement, then each substatement recursively may also be labeled. Example:
switch(x) {
if(1) one: case 1: dothis();
else case 0: orthis(); /*fallthru*/
three: case 3: three();
}
The syntax treats case
/default
-labels and regular labels the same, only the semantic check verifies that case
/default
-labels be inside a switch
.
Implementation-wise, everything compiles into (flat) assembly.
E.g.
if(test) YesBranch; else ElseBranch;
is flattened into (pseudo-assembly)
IF_NOT_THEN_GOTO(test, PAST_YES_BRANCH)
YesBranch
goto PAST_NO_BRANCH;
NoBranch
PAST_NO_BRANCH:;
and there's no reason why anything in such flat code couldn't be labeled.
case
/default
labels are also just like regular labels except they're also used in (most usually) a computed jump.