5 Secrets of the Switch Statement

If you’re like me then you might feel that the switch statement stands out awkwardly among other programming constructs. Obviously everything in the programmer’s tool set is meant to provide a unique advantage, but the switch statement seems particularly quirky in both syntax and behavior.

Recently I was researching the deeper levels of the C programming language and I stumbled on some interesting facts that may help to understand the switch statement better. Even though I was reading about C, I believe they apply to most programming languages, especially those derived from C.

1. The minimum number of cases a compiler must permit is 256.

You may have been using the switch statement for years without ever wondering if there is a limit to the number of cases you can use. Yes, there is a limit, but it varies from language to language.

That said, it’s a safe bet that your compiler must use a minimum of an 8-bit character for addressing all possible cases. Thus allowing for at least 256 total possibilities.

Most programming languages employ a higher minimum. The C specification requires that compilers support 1023 cases. I believe C++ is even higher.

2. You can declare local storage by following the switch’s open curly brace with a declaration.

Curly braces are delimiters for compound statements — a grouping of statements for a singular use, such as to form the body of a loop or conditional. Compound statements usually have their own scope. So you can declare variables inside the curly braces of a switch statement just as you can inside a loop.

In the following example C example, I declare an integer inside a switch statement, prior to any cases:

int a = 1;
switch (a) {
int b; // Declare variable inside switch
case 1:
b = a;
printf("b = %i", b);
break;
}

Output:

b = 1

I’m not sure if there is a practical use for this. If you need a variable that is scoped only for the switch statement then it could save the day. But I suspect that for most programmers it’ll be nothing more than an interesting quirk.

3. Execution starts after the matching case.

I am sure this isn’t a surprise to experienced programmers, but it’s worth mentioning a quirk that results from this behavior.

In my previous code example, notice that when I declared “int b”, I didn’t initialize it with a value. Had I given b an initial value like so:

int a = 1;
switch (a) {
int b = a; // Declare variable with initial value
...

… the compiler would have never executed it, and b would have remained uninitialized at runtime. That’s because execution inside a switch statement starts after the matching case. Since this assignment is above the matching case, it is never executed.

Space for b is still allocated and available after execution begins because the compiler allocates space prior to runtime as a separate step.

4. The default case can be in any position in the case list.

By convention the default case is usually last, but it doesn’t have to be. The compiler is perfectly happy with a default case being in any position.

If you are breaking all of your cases to prevent fall-through, then where you place the default case doesn’t matter much. But if you are making use of the fall-through feature, then it may present some interesting possibilities.

Consider an example where you want all cases to execute by default:

switch (get_choice()) {
default:
case 1:
// case-specific code
case 2:
// case-specific code
case 3:
// case-specific code
}

Or just the second and third cases:

switch (get_choice()) {
case 1:
// case-specific code
default:
case 2:
// case-specific code
case 3:
// case-specific code
}

With that said, it is rare that developers actually use the fall-through feature, as we’ll see next.

5. Fall-through is used so infrequently that some considered it a design flaw.

Peter Van Der Linden, author of “Expert C Programming”, wrote this about the switch statement and it’s fall-through feature:

Fall-through was intended to allow common end processing to be done after some case-specific preparation had occurred. In practice it’s a severe misfeature, as almost all cases end with a break.

He further analyzed the Sun C compiler to see how often fall-through was used. Of 244 switch statements, each with 7 cases on average, fall-through occurred in 3% of cases.

His conclusion was that since fall-through was used so infrequently, it should be considered a design flaw, and to that end, the C specification should be amended to require cases to break automatically.

Some languages, such as Swift, are starting to take action on this issue, breaking by default, and adding a fallthrough command to be used when it’s desired.