TRT
Sign in
easyFoundationsconcept

How does a compiler lower a switch statement into a jump table, and when is it faster than an if/else chain?

Explain O(1) indirect dispatch via a contiguous jump table versus O(n) sequential comparisons or binary search trees for sparse case labels.

TRT practice prompt — not a verified question from a named employer.

The Runtime Theory Team2 min read
Learn it firstControl Flow and Branching MechanicsUnderstand CPU condition flags, predict branch predictor costs, explore compiler jump tables in switch statements, and structure clean goto unwinding.

A strong answer

An if / else if chain of $N$ branches compiles into a sequence of $N$ comparison and conditional jump instructions (cmp + je), requiring $O(N)$ comparisons in the worst case. A switch statement requires every case label to be a compile-time integer constant expression. When the case values are dense (for example, case 0: through case 7:, or an enum of opcode IDs), the compiler lowers the switch into a jump table: a read-only array of code addresses stored in .rodata. At runtime, the CPU subtracts the minimum case value, performs one bounds check against the maximum case value, and executes a single indirect jump jmp *table(,%rax,8). That dispatches to any of 100 cases in $O(1)$ constant time with a single branch instruction.

If the case labels are sparse (such as case 1:, case 1000:, case 1000000:), allocating a million-entry jump table would waste megabytes of memory. In that situation, the compiler automatically lowers the switch into a balanced binary search tree of comparisons ($O(\log N)$ tests) or a compact comparison chain.

Because case labels compile to plain assembly labels inside a single contiguous block of instructions, execution simply continues into the next case's instructions unless you explicitly jump to the end of the switch with break—a behavior known as fall-through.

What the interviewer is listening for

  • Explains how dense integer case labels enable an $O(1)$ indirect jump table in .rodata.
  • Notes that sparse case labels fall back to $O(\log N)$ binary search comparisons rather than wasting memory on a sparse table.
  • Connects case fall-through directly to how labels work in machine assembly (case is an entry label, not a scoped block boundary).

Common mistakes

  • Assuming every switch is always a jump table even when case constants are millions apart.
  • Forgetting break at the end of a case and accidentally executing the next case's code (use -Wimplicit-fallthrough to catch unintended fall-throughs at compile time).
  • Declaring and initializing a variable directly inside a case label without wrapping the case body in {} braces.

This answer walks

Practice follow-ups

  1. 01What happens at the assembly level if you omit break at the end of a switch case?
  2. 02Why can't a C switch statement match strings or runtime variables in its case labels?

Not started

Sign in to save your learning progress.

Sign in to save