#4. Avoid fall-through in nonempty cases of "switch" statements

Each case label in a switch statement shall be followed by one of the following:
  • Any number of statements, followed by a break instruction.
  • Another case label.
  • A default label.
Do not write statements below a case label and without a break instruction after them. It is confusing.

A switch statement is a controlled jump. Every time the code execution encounters the keyword switch, it will jump to a different place. The question is where. And the answer is:
  • To the case which is equal to the value of the expression in the switch, if there is one;
  • To the default case, if there isn't one of the above and it exists;
  • To the line after the closing bracket in the switch block, otherwise.
In the first case, when the break instruction is reached, the execution flow will jump to the line after the closing bracket in the switch block.

Or should I say "if"? The break instruction is actually optional. You could omit it, and the execution flow would fall through to the instructions after the next case label.

This would be legal, but very confusing. You should avoid it.

Let me quote this StackOverflow answer, which in turn quotes a designer of the C# language argumenting against fall-through between cases being built into the language (C# doesn't have fall-through between cases):
This implicit fall-through behavior is often used to reduce the amount of code needed and often isn't an issue the first time that code is written. However, as code moves from the initial development phase into a maintenance phase, the code above can lead to subtle errors that are very hard to debug. These errors result from the very common mistake of the developer adding a case, yet forgetting to put a break at the end of the block.
In C#, the switch statement requires that explicit flow control occur at the end of a case, either a break, goto, return, or throw. If the developer desires fall-through semantics, it can be achieved by an explicit goto at the end of a case statement.
There is not one single truth, except maybe for the fact that you need to know the syntax of your language and use it correctly. But I am strongly inclined to treat C++ as if it was C# in this particular item: do not use fall-through, and always use break at the end of a nonempty switch statement. This will make your C# and C++ switch statements look the same, and behave in the same way - a robust, less error prone way.

Bibliography

[McConnell 2004]
Steve McConnell: Code Complete, 2nd Edition, Microsoft Press, 2004.

This book discusses switch statements in Chapter 15: "Using conditionals", Section 15.2 "case statements" (pages 361-365).

Comments

Popular posts from this blog

#13. Organize your code in classes

#2. Make all type conversions explicit

#5. "for" loops should be simple and well-formed