A switch statement is a multi-way branch control flow construct that selects one of many code blocks to execute based on the value of an expression. Switch statements provide a more readable and potentially more efficient alternative to long chains of if-else statements.
switch (expression) {
case constant1:
// code block 1
break;
case constant2:
// code block 2
break;
default:
// default code block
break;
}
Switch statements have specific restrictions that enable efficient implementation:
These restrictions allow the compiler to implement switches using jump tables for efficient O(1) branching.
For sparse cases or few options, the compiler uses sequential comparisons:
if (i == 20) {
j = 10;
} else if (i == 21) {
j = 11;
} else if (i == 42) {
j = 12;
} else {
j = 14;
}
For dense cases, the compiler uses a jump table:
// Original switch
switch (i) {
case 20: j = 10; break;
case 21: j = 11; break;
case 22: j = 12; break;
default: j = 14; break;
}
// Equivalent with jump table
void *jt[3] = { &&L20, &&L21, &&L22 };
if (i < 20 || i > 22) goto DEFAULT;
goto *jt[i - 20];
L20: j = 10; goto CONT;
L21: j = 11; goto CONT;
L22: j = 12; goto CONT;
DEFAULT: j = 14;
CONT:
In SM213 Assembly, jump tables enable efficient switches:
ld $i, r0 # r0 = &i
ld (r0), r0 # r0 = i
# Check bounds: if i < 20 or i > 22, goto default
ld $-20, r1
add r0, r1 # r1 = i - 20
ld $0, r2
bgt r2, r1 # if r1 < 0 (i < 20), goto default
ld $3, r2
bgt r1, r2 # if r1 > 2 (i > 22), goto default
# Jump through table
ld $jmptable, r2
j *(r2, r1, 4) # jmptable[i - 20]
case20:
ld $10, r1
br done
case21:
ld $11, r1
br done
case22:
ld $12, r1
br done
default:
ld $14, r1
br done
done:
ld $j, r0
st r1, (r0)
jmptable:
.long case20
.long case21
.long case22
The compiler chooses the implementation strategy based on:
| Cases | Strategy | Reason |
|---|---|---|
| Sparse (large gaps) | If-else chain | Jump table would waste memory |
| Few cases (<4-5) | If-else chain | Simpler, similar performance |
| Dense (small gaps) | Jump table | O(1) lookup, worth the space |
| Large range | If-else chain | Jump table too large |
Without break, execution continues to the next case:
switch (i) {
case 1:
printf("One ");
// falls through
case 2:
printf("or Two\n");
break;
}
This is rarely desired and often causes bugs, which is why compilers warn about missing break statements.