4

As far as I can tell in all C-like languages something like this:

switch(variable) {
    case 'a':
        printf("Hello ");
    case 'b':
        printf("World!");
    case 'c':
        printf("\n");
}

Will print "Hello World!" if variable == 'a'. I'm curious about the reasoning behind this behaviour as it seems to me automatically inserting breaks at the end of every case would make its behaviour a lot more consistent with expectations and a lot less error-prone.

For example: "In case your die rolls a 6, draw another card" is an action that has to be done in a single case, which to me the case keyword implies.

2
  • 2
    Failing to find a problem for a well known solution is generally not proof that someone else didn't have the problem in the first place, just that you didn't look very hard for the original problem.
    – Don Simon
    Feb 17, 2015 at 17:48
  • 3
    @DonSimon which is the whole reason I'm asking.
    – Bartvbl
    Feb 17, 2015 at 17:55

4 Answers 4

12

To write the equivalent of a switch statement in assembly you'd need to add jumps at the end of each branch to prevent execution from continuing to the next branch. C was designed to have a fairly straightforward mapping to machine code, and the pattern would've been familiar to assembly programmers at the time.

Its descendants likely kept it out of historical inertia, which should not be underestimated. For example, the designers of C# clearly felt accidental fall-through is a major source of bugs and is the uncommon case, so you need to explicitly fall through if you want it, but they still kept the syntax of adding a break at the end!

3
  • 1
    C# doesn't allow fall-through - every case code block must end with some sort of jump statement. It does, however, allow multiple case labels for the same code block. Feb 18, 2015 at 0:46
  • @RossPatterson I consider jumping to the next label a form of explicit fall-through, but I suppose the wording is a bit misleading.
    – Doval
    Feb 18, 2015 at 0:51
  • Yes, perhaps, but I wouldn't call C#'s multiple-label-per-block syntax either fall-through or jumping. Feb 18, 2015 at 23:59
5

That is because you can't assume that logic and program flow should stop after a single match. It is a good design for a multiple-match type of conditional test.

Take this for example:

switch (shape)
{
    case Square:
        printf("I am a square\r\n");
    case Rectangle:
        printf("I am a rectangle\r\n");
        break;
    case Circle:
        printf("I am a circle\r\n");
        break;
}

If we didn't have the fall through behavior here, we'd have to be redundant with printf("I am a rectangle\r\n"); in order to have that code execute for both a square and a rectangle.

5
  • Can you give an example of where this would be useful?
    – Bartvbl
    Feb 17, 2015 at 17:41
  • @Bartvbl: A multiple-match conditional test is a case where more than one value can satisfy the switch condition. It is the only exception that the C# language makes for fall-through behavior. Feb 17, 2015 at 17:43
  • 1
    @Bartvbl en.wikipedia.org/wiki/Duff%27s_device
    – Mephy
    Feb 17, 2015 at 18:06
  • 2
    @Bartvbl: I wrote a switch statement a few years ago to interpret html colour values, notably the #rgb and #rrggbb syntaxes. To avoid repeating code, I had the #rgb case convert the value to #rrggbb format, then falling through to that case
    – 3Doubloons
    Feb 17, 2015 at 18:43
  • @Mephy Duff's device should never be used in real code; the compiler is generally better at making such optimizations than the programmer. On the other hand, it did inspire Simon Tatham's implementation of coroutines in C, which is IMHO the best use of this facility I've ever seen...
    – Jules
    Apr 11, 2015 at 0:22
4

Case statement fall through is rarely needed, but it does sometimes happen. (I have heard that C was originally meant to program telephone switchboards, in which this need arises often, but I was unable to confirm it.) But the truth is that even in modern software, the need for a case statement fall through does arise every once in a rare while.

If the C language did not allow case statement fall-through, then workarounds would be necessary, but the line of thinking back in 1972 was to avoid wasting clock cycles. By allowing case statement fall-through, programmers could have it both ways: you could either fall through or break, whichever was pertinent to your needs, on a case per case basis.

The primary focus of the C language originally was to be nice to the machine, not nice to the programmers. The original C was lean, mean, and very unforgiving.

The idea behind preventing case statement fall through is a very modern concept, and it is all about protecting programmers from themselves. Very few people were thinking along such lines in AT&T Bell Labs back in 1972, when C was invented.

7
  • Agreed, but as far as I know the first Unix machines were running some patent text processing application and were not running real-time telephone switching systems! Feb 17, 2015 at 19:00
  • 2
    This doesn't sound quite right. According to The History of C, C emerged because the team that was developing Unix wanted to program in a higher level language. There's not a single mention of telephone switchboards, and "at the time [they] did not put much weight on portability; interest in this arose later." Apparently around 1977, which is about 4-5 years after C could be recognized as such.
    – Doval
    Feb 17, 2015 at 19:02
  • @BasileStarynkevitch Yes, that bit about telephone switchboards is something that I was told once, but I was unable to confirm it, so I reworded my answer.
    – Mike Nakis
    Feb 17, 2015 at 19:05
  • @Doval Yes, that bit about telephone switchboards is something that I was told once, but I was unable to confirm it, so I reworded my answer.
    – Mike Nakis
    Feb 17, 2015 at 19:06
  • @Mike Nakis: maybe you were thinking of Erlang? Feb 17, 2015 at 20:18
0

See Stack Overflow.

A summation of the popular arguments presented there is that:

  1. A switch statement can provide fallthrough while still allowing you to have a choice about it with the break statment.
  2. It was a mistake in the design of C that ended up becoming the standard for case statments.

Not the answer you're looking for? Browse other questions tagged or ask your own question.