The switch matched case 5 — so it runs case 5’s code and leaves, right? Not in C. This question from our C Programming Quiz App is about fallthrough, the single most surprising rule of the switch statement, responsible for decades of bugs and one legendary telephone-network outage.
The Quiz Question
int x = 5;
switch (x) {
case 5: printf("five");
case 6: printf("six");
default: printf("other");
}
What is printed by this code?
- five
- fivesix
- fivesixother
- other
The Correct Answer: fivesixother
A case label is just that — a label, a jump target. The switch jumps to case 5 and from there execution simply flows downward, straight through case 6 and default, because nothing tells it to stop. Verified on gcc 13.3 and Apple clang 21:
$ gcc -ansi -Wall -Wextra fall.c && ./a.out fivesixother
gcc’s -Wextra even flags each boundary on the way down:
warning: this statement may fall through [-Wimplicit-fallthrough=]
6 | case 5: printf("five");
| ^~~~~~~~~~~~~~
(clang has the same warning but doesn’t enable it via -Wall -Wextra for C — another case where compiling with both toolchains catches more.)
Why Each Wrong Answer Is Wrong
Why not “five”?
“five” is what the break-terminated version prints — and what most other languages do by default. We ran that version too:
switch (x) {
case 5: printf("five"); break;
case 6: printf("six"); break;
default: printf("other");
}
$ ./a.out five
In C the isolation between cases is opt-in: no break, no boundary.
Why not “fivesix”?
Half-fallthrough — as if default were somehow protected. It isn’t: default is one more label in the same statement list, and execution falls into it exactly as it fell into case 6. Position matters, not the keyword.
Why not “other”?
default is the jump target only when no case matches. Here case 5 matched, so the switch entered at case 5 — default ran, but only because control flowed down into it.
Fallthrough: Bug Magnet and Occasional Feature
Why does C work this way? Because switch is a thin veneer over a computed jump — the case labels mark entry points into one shared statement list. That design makes intentional fallthrough possible, and it has legitimate uses — stacking cases that share a handler:
switch (c) {
case ' ': case '\t': case '\n': /* all whitespace */
skip++;
break;
case '0': case '1':
digits++;
break;
}
But accidental fallthrough — a forgotten break — is one of C’s most notorious bug classes; the 1990 AT&T long-distance network collapse traced back to a misplaced break in a switch. Modern practice: end every non-empty case with break (or return), and when fallthrough is intentional, say so — a /* fall through */ comment silences gcc’s warning, and C23 standardized the [[fallthrough]]; attribute for exactly this.
Frequently Asked Questions
What happens if you omit break in a C switch?
Execution falls through into the next case’s statements — and keeps going through every following case and default until it hits a break or the end of the switch. Matching case 5 here runs all three printfs.
Does default only run when no case matches?
default is entered only when no case matches — but it can also be reached by fallthrough from a case above it, as in this question. A break on the last case before default prevents that.
Is switch fallthrough ever useful?
Yes — grouping multiple case labels over one shared handler is idiomatic and safe (the labels are adjacent with no statements between them). Falling through after executing statements is the risky kind; mark it with a comment or C23’s [[fallthrough]];.
Related Reading
- The continue Statement in C – Skipping an Iteration
- Equality Operator in C – Why 3 == 3 Prints 1
- Ternary Operator in C
- C Aptitude Questions and Answers
Recommended Books
- The C Programming Language – Kernighan & Ritchie (India) | Amazon.com
- C Programming: A Modern Approach – K.N. King (India) | Amazon.com
This question is #99 in the C Programming Quiz App — 155 questions with explanations covering basics, operators, pointers, and more.
Download on Google Play →