Control Flow
Switch-Case
Multi-way branching with switch
Interview: Alternative to if-else chains
Switch-Case Statements
A switch statement implements multi-way branching based on an integral or enum value. Internally, the compiler may optimize it into a jump table (O(1) lookup) or a series of comparisons depending on the density of case values. This often makes switch faster than long if-else chains for many constants.
Fall-Through Behavior
Without a break, execution falls through to the next case label automatically. This is intentional design (useful for grouping cases) but a frequent source of bugs. C++17 introduces [[fallthrough]] attribute to document intentional fall-through and suppress compiler warnings.
Switch on Strings?
Standard switch statements cannot operate on std::string directly — only integer types and enums. For string-based dispatch, use std::unordered_map<std::string, std::function<void()>> or if-else chains. C++23 pattern matching proposals may address this in the future.
Interview Corner
Q: How does the compiler optimize switch statements into jump tables?
A: When case values are densely packed integers, the compiler builds an array of function pointers or code addresses indexed by the value. The switch becomes a single array lookup and indirect jump — O(1) regardless of the number of cases. Sparse or non-contiguous values may fall back to binary search or if-else chains.
Q: What is the [[fallthrough]] attribute and when do you use it?
A: [[fallthrough]] is a C++17 attribute placed before a case label to explicitly document that fall-through from the previous case is intentional. Without it, some compilers emit warnings. It communicates intent to both the compiler and human readers.
Common Pitfalls
- Missing break: Forgetting break causes unintended fall-through to subsequent cases, executing unintended code silently.
- Variable declarations in case blocks: Declaring variables with initializers in case blocks without an enclosing
{}scope causes compilation errors since the jump may bypass initialization.
Best Practices
- Always include a
defaultcase to handle unexpected values safely. - Use
[[fallthrough]]when fall-through is intentional to document the design decision. - Prefer
enum classwith switch over integer constants for type-safe exhaustive matching.