switch and fall-through
When one variable is compared with several numbers, an else if chain repeats the same comparison in every branch. A switch statement 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";
}
}A case with a constant and a colon is a label: where execution jumps when the expression equals that constant. break ends the switch. The default label runs when no case label matches. Without default, nothing runs then.
Which values fit
The expression in a switch must have an integer or enumeration type: int and char fit, while double does not. A case takes a constant known at compile time: a literal such as 2 or 'a', or a constexpr variable. 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
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. It 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 prints vowel. A letter that has no label goes to default.
If the next label already has code before it, 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;
}When level is 1, execution starts at case 1: and prints only user.
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: this statement may fall through [-Wimplicit-fallthrough=]When day is 1, the program prints both Monday and Tuesday: execution falls through into case 2. GCC warns about this with the -Wextra flag, and Clang only with -Wimplicit-fallthrough. End every branch with break, and mark an intended fall-through with [[fallthrough]].