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

switch(variable) {
    case 'a':
        printf("Hello ");
    case 'b':
    case 'c':

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
    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 '15 at 17:48
  • 3
    @DonSimon which is the whole reason I'm asking. – Bartvbl Feb 17 '15 at 17:55

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!

| improve this answer | |
  • 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. – Ross Patterson Feb 18 '15 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 '15 at 0:51
  • Yes, perhaps, but I wouldn't call C#'s multiple-label-per-block syntax either fall-through or jumping. – Ross Patterson Feb 18 '15 at 23:59

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");
    case Circle:
        printf("I am a circle\r\n");

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.

| improve this answer | |
  • Can you give an example of where this would be useful? – Bartvbl Feb 17 '15 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. – Robert Harvey Feb 17 '15 at 17:43
  • 1
    @Bartvbl en.wikipedia.org/wiki/Duff%27s_device – Mephy Feb 17 '15 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 '15 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 '15 at 0:22

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.

| improve this answer | |
  • 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! – Basile Starynkevitch Feb 17 '15 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 '15 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 '15 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 '15 at 19:06
  • @Mike Nakis: maybe you were thinking of Erlang? – Lauri Laanti Feb 17 '15 at 20:18

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.
| improve this answer | |

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