switch and fall-through
A big building has a directory in its lobby: "Accounts: floor 3, HR: floor 5, canteen: floor 1." You don't walk every floor in turn. You find your line in the directory and take the lift straight to the right floor.
An else if chain is like walking every floor. When one variable is compared with several numbers, an else if chain compares that same variable with a new number in every branch. A switch statement works like the lobby directory: it evaluates the expression in parentheses once and jumps to the branch with the same value:
#include <iostream>
int main() {
int day = 2;
switch (day) {
case 1:
std::cout << "Monday\n";
break;
case 2:
std::cout << "Tuesday\n"; // Tuesday
break;
default:
std::cout << "another day\n";
}
}Let's walk through the program:
switch (day)evaluatesdayand gets2.- Execution jumps straight to the
case 2:label and printsTuesday. breakends theswitch, sodefaultis never reached.
The case and default labels
A case with a constant and a colon is a label: where execution jumps when the expression equals that constant. In the lobby directory, a label is the line with a floor number.
breakends theswitch.- The
defaultlabel runs when nocaselabel matches. - When no label matches and there is no
default, no branch runs.
Which values fit
A switch has some limits:
- the expression in a
switchmust have an integer type:intandcharfit, whiledoubledoes not; - a
casetakes a constant known at compile time: a literal such as2or'a', or aconstexprvariable; - two labels with the same value do not compile.
A switch checks only for equality. A condition such as day > 5 cannot be written as a label, so ranges still need an else if chain.
Fall-through
This is where the lift analogy ends. A lift stops at your floor, while a switch without break keeps going.
A label does not end the code that comes before it. Without break, execution goes on through every following label, default included, until a break or the end of the switch. This is called fall-through.
Step through the program and watch where execution enters the switch and where it leaves:
1–2#include <iostream>3int main() {4 int level = 2;5 switch (level) {6 case 3:7 std::cout << "owner\n";8 case 2:9 std::cout << "admin\n";10 case 1:11 std::cout << "user\n";12 break;13 default:14 std::cout << "guest\n";15 }16 std::cout << "done\n";17}
The variable level is 2
Fall-through lets several labels share one branch:
char c = 'e';
switch (c) {
case 'a':
case 'e':
case 'o':
std::cout << "vowel\n"; // vowel
break;
default:
std::cout << "other\n";
}When c is 'e', execution jumps to the case 'e': label, passes the empty case 'o': label, and the program prints vowel. A letter that has no label goes to default.
If a branch has code of its own before the next label, an intended fall-through is marked with the line [[fallthrough]];. It does not change what the program does. It tells the compiler and the reader that the missing break is intended:
int level = 2;
switch (level) {
case 2:
std::cout << "admin ";
[[fallthrough]];
case 1:
std::cout << "user\n"; // admin user
break;
}Let's look at both cases:
- When
levelis2, the program printsadmin, falls through intocase 1:and printsuserafter it. The result isadmin user. - When
levelis1, execution starts atcase 1:, and the program prints onlyuser.
Common mistake
A branch is missing its break:
int day = 1;
switch (day) {
case 1:
std::cout << "Monday\n"; // ✗
case 2:
std::cout << "Tuesday\n";
break;
}warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough]When day is 1, the program prints both Monday and Tuesday: execution falls through into case 2. Clang warns about this only with the -Wimplicit-fallthrough flag, while GCC already warns with -Wextra. End every branch with break, and mark an intended fall-through with [[fallthrough]]. What a switch without break prints is a common interview question.
Key points
- A
switchevaluates the expression once and jumps to thecaselabel with the same value, or todefaultwhen there is none. - The expression in a
switchhas an integer type, and acasetakes a constant known at compile time. - Without
break, execution falls through the following labels until abreakor the end of theswitch. - An intended fall-through is marked with
[[fallthrough]];.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.