When the switch statement is executed, its variable/expression is evaluated, and that value compared to each of the case statements. If it matches one, execution jumps to that case statement and its following code (If none match, it will jump to the "default" statement if there is one). However when the end of that code is reached (at least in C), it doesn't automatically jump back out of the switch statement unless there is a break statement in there to make it do so, or it reaches the very end of the switch block; instead, it will just keep going through the next case statement, and the next, until it's stopped by a break or the end. This can cause people problems if they forget, but it makes a degree of sense at the implementation level and can have some uses.
I gather that some other languages that features switch/case-like constructs do not use fallthrough. Ruby for instance, uses a "case/when" structure, where the "break" statements for each "when" clause is implicit, so fallthrough isn't possible, and writing multiple conditions for a given piece of code is handled differently.
for(day=1;day<=12;day++) { /* outer loop counting from 1 to 12 */
switch(day) { /* we want the suffix right at the start of each day */
case 1: suffix="st"; break;
case 2: suffix="nd"; break;
case 3: suffix="rd"; break;
default: suffix="th";
}
printf("On the %d%s day of Christmas, my true love gave to me:\n", day,suffix);
/* for those unfamiliar with the printf() function, the %d and %s there */
/* get replaced by the extra arguments (in this case, day and suffix). */
/* The fact 'day' starts with 'd' and 'suffix' starts with 's' is purely */
/* coincidental, the use of %d vs %s is to do with whether the value */
/* is a decimal number or a string of text. */
switch(day) { /* note the fall-through */
case 12:
printf("12 Lords a leaping, ");
case 11:
printf("11 Maids a milking, ");
case 10:
printf("10 Drummers drumming, ");
case 9:
printf("9 Badgers badging, ");
case 8:
printf("8 Geese a laying, ");
case 7:
printf("7 Swans a swimming, ");
case 6:
printf("6 Pipers piping, ");
case 5:
printf("5 Gold rings!\n");
/* I guess "bling" culture is nothing new */
case 4:
printf("4 Calling birds, ");
case 3:
printf("3 French hens, ");
case 2:
printf("2 Turtle doves, and ");
case 1:
printf("A Partridge in a pear tree.\n");
break; /* now finally we break to exit the switch block */
/* (only necessary if we have a default case after) */
default:
printf("Socks\n");
/* no break necessary here, because it's end of block */
}
printf("\n"); /* an extra blank line for good measure*/
}
(note, this routine will not actually compile as-is, it lacks headers, a main() function, and variable declarations, and otherwise hasn't been bug-tested)
It's possible there's even more useful applications for fall-through, the example above is in a way rather like the optimisation technique of "loop unrolling", popular in compilers. With this though, the loop being replaced can be variable length, but must end at a fixed point, so it'd be good for inner loops (like the above) that count down from somewhere to 1 or (rather more likely) 0. But the loops would have to have a well-defined upper bound for the starting point, and that couldn't (for practical and technical reasons) be too high.
A very nice illustration of this problem is shown in a long-running Nethack bug re the attack of a particular monster. Note that the problem had not been so much that fallthrough was used (although the code could have been easily written without it), but that it wasn't clearly enough marked. A much better comment would have been "Fall through to default case for 0 damage" or similar. "Fall through to next case" is redundant vs just "Fall through", as there is no other case you can fall through to than the next case -or ok, the end of the block I suppose. As it was, it would seem that the bug was unreported for about 8 years, because those who encountered it didn't realise that attack wasn't meant to be lethal.
Ultimately this is related to the problem that the notion of "you don't need comments, just write readable code" is flawed: it depends on your code being (1)flawless, and (2)clearly and unambiguously what you intended. But it is also a clear illustration that merely having "comments" isn't good enough if the comments don't actually show your intentions sufficiently.