12

I just discovered the following section in some code I maintain:

switch (m) {
    case 62: { // opening
        // some declarations
        // do some stuff
        break;
    case 63:
        // do some other stuff
        break;
        }      // closing
    default:
        // default stuff
        break;
 }   

The block opening is meant to declaring some local variables, but the closing brace is wrongly placed and occurs after the case 63.

I have never noticed this for months as it compiles well in Visual Studio 2010. I've tried debugging it and both cases work fine.

How can it be ? Is this correct C syntax ?

wap26
  • 2,180
  • 1
  • 17
  • 32
  • 1
    Is `case 63` reachable through the `switch`? – wallyk Jan 28 '13 at 20:40
  • You may have a look at [this](http://stackoverflow.com/questions/92396/why-cant-variables-be-declared-in-a-switch-statement). The curly-braces define scope for the variables declared inside. – Ben Lu Jan 28 '13 at 20:40
  • @wallyk, yes! This is what surprised me. – wap26 Jan 28 '13 at 20:41
  • If `case 63` did have some variable declarations, it _would_ be incorrect syntax, then. But since there isn't... – librin.so.1 Jan 28 '13 at 20:51

3 Answers3

16

The case statements are just like goto labels and so that is allowed syntax. Duff's device is a famous use-case.

Try to avoid doing it though.

Pubby
  • 51,882
  • 13
  • 139
  • 180
5

6.8.1 Labeled statements, C99

Any statement may be preceded by a prefix that declares an identifier as a label name. Labels in themselves do not alter the flow of control, which continues unimpeded across them.

i.e. The curly braces have no effect on how the switch-case labels work but it merely creates a new scope.

This explains why the seemingly misplaced curly braces don't result in a syntax error.

P.P
  • 117,907
  • 20
  • 175
  • 238
4

Surprisingly, this is correct syntax per the language standard. You can even do this:

switch (m) break;

or this:

switch (m);

case const-expr: works pretty much like a regular label that you'd use with goto.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180