1

This code works for some reason but it does not make sense at all.

#include <stdio.h>

int main(void)
{
  switch(1)
    {
      case 0:
        while(1)
          {
            case 1: puts("Works"); break;
          }
    }
  return 0;
}

Can someone explain why it does work and what applications does this have?

mrk
  • 3,061
  • 1
  • 29
  • 34

3 Answers3

8

The case labels are almost exactly like labels used by goto.1 If you think of your code in those terms, it should be clear that it's valid. Namely, you can consider a switch statement to be a glorified conditional goto.

That said, I would slap anyone who wrote code like that in a production environment.2


  1. In fact, they are both listed in the same grammar section (6.8.1) of the C99 standard.

  2. Yes, this is almost identical to Duff's device, but that last had any practical use decades ago.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
5

The reason this works is somewhat non-intuitive: case labels of a switch statement act very much like regular labels, i.e. the ones designed for use with goto statement. You can place such labels anywhere in your code.

It turns out that the same rule applies to the case label: you can place them anywhere inside their corresponding switch statement, which incidentally includes the bodies of any nested loops.

The reasons why you may want to place labels inside control statements within the body of your switch statement are even less intuitive: it turns out that you can perform loop unrolling with a cumbersome-looking but very intuitive construct called Duff's Device. It is this construct that lead to popularizing the idea of embedding case labels inside other control structures within switch statements.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thanks. What's loop unrolling? I'm interested – mrk Mar 06 '13 at 19:01
  • 1
    @saadtaame Loop unrolling (AKA "loop unwinding") is when you repeat the body of a loop several (say, four) times, and simultaneously decrease the number of times the loop executes. This does the same amount of work with less iteration, thus decreasing per-iteration costs (checking the exit condition and incrementing indexes). Here is [a link to a wiki article](http://en.wikipedia.org)./wiki/Loop_unwinding – Sergey Kalinichenko Mar 06 '13 at 19:03
4

You can interleave statements through the labels of switch, since they're just labels. What happens here is:

  • you have an infinite loop defined using while (1);
  • the switch (1) statement jumps to the case 1: label;
  • where "Works" is printed, then break; exits the inifinite loop.