Ch3.9: switch
The switch Statement
A switch statement selects one branch based on the value of an
expression.
It is often clearer than writing many if / else if chains.
switch (expr) {
case value1:
stmt1;
break;
case value2:
stmt2;
break;
default:
stmt_default;
break;
}
Each case label matches a constant value.
break prevents execution from falling through to the next case.
Basic Example
::std::int_least32_t x{2};
switch (x) {
case 1:
println("one");
break;
case 2:
println("two");
break;
default:
println("other");
break;
}
Fallthrough Behavior
If a case does not end with break, execution continues
(“falls through”) into the next case.
::std::int_least32_t x{1};
switch (x) {
case 1:
println("one");
// no break here → fallthrough
case 2:
println("two");
break;
}
This prints:
one
two
Fallthrough is allowed, but should be used intentionally.
C++ Attributes
C++ provides a standard syntax for attaching extra information to code:
[[attribute_name]]
Attributes do not change the meaning of the program, but they can give hints to the compiler or improve clarity for readers.
The [[fallthrough]] Attribute
When you intentionally allow fallthrough in a switch, you should
mark it with [[fallthrough]].
This makes the intent clear and avoids compiler warnings.
switch (x) {
case 1:
println("one");
[[fallthrough]]; // intentional fallthrough
case 2:
println("two");
break;
}
The attribute must appear as a standalone statement.
default Case
The default label runs when no other case matches.
switch (x) {
case 0:
println("zero");
break;
default:
println("not zero");
break;
}
Multiple Cases for One Branch
switch (x) {
case 1:
case 3:
case 5:
println("odd small number");
break;
default:
println("other");
break;
}
Nested switch
switch (x) {
case 1:
switch (y) {
case 0:
println("x=1, y=0");
break;
default:
println("x=1, y!=0");
break;
}
break;
default:
println("x!=1");
break;
}
Pseudo-graph: switch
┌───────────────┐
│ switch(expr) │
└───────┬───────┘
│
▼
┌──────────────────────┐
│ match a case? │─── no ───▶ default
└──────────┬───────────┘
│ yes
▼
┌───────────────┐
│ case block │
└───────┬───────┘
│
├──▶ break ─────────────▶ end
│
└──▶ fallthrough ───────▶ next case
Key takeaways
- switch selects a branch: based on the value of an expression.
- case labels: must be constant expressions.
- break prevents fallthrough: without it, execution continues.
- [[fallthrough]]: marks intentional fallthrough.
- default: runs when no case matches.
- Multiple cases: can share the same block.
- Nested switches: allowed but should be used carefully.