2

I know that C++03 doesn't allow to define variables within switch block without using curly braces.

const int i = ...
switch (i) { case 0: int j = 0; break; } // 1. error here
switch (i) { case 0: { int j = 0; } break; } // 2. ok

What is regarding new C++11 standard? Does it allow first form? Can I also write something like this:

switch (i) 
{ 
  case 0: int j = 0; break; 
  case 1: int j = 0; break; 
  case 2: int j = 0; break; 
} 
4xy
  • 3,494
  • 2
  • 20
  • 35

3 Answers3

4

The case statement did not (in C++03) and still does not (in C++11) introduce a scope.

The standard says in [stmt.switch] (6.4.2/6):

case and default labels in themselves do not alter the flow of control, which continues unimpeded across such labels.

Thus it is allowed to "fall through" case statements like this:

int x, a = 1;
switch(a) {
case 1:
    x = 5;
    // no break here!
case 10:
    x *= 4; // x is now 20.
}

If you would introduce a varible declaration for example below the first case statement, it could be skipped when a jump to the second case statement would happen.

You can however declare a local variable right at the start of the switch block:

switch (i) 
{
    int j;
case 0: j = 0; break; 
case 1: j = 0; break; 
case 2: j = 0; break; 
}

A switch is really more a jump table than a series of if/else if statements.

Danvil
  • 22,240
  • 19
  • 65
  • 88
  • I never knew you could declare variables before the first case label. – Mark Ransom Apr 29 '14 at 18:45
  • @MarkRansom You can have pretty much anything there (`switch (3) { puts("Huh?!"); }`), which is almost never useful, but a variable declaration is one of the few exceptions where it is useful. –  Apr 29 '14 at 19:10
  • 1
    @MarkRansom: Something else similar, interesting, and perhaps surprising that one can do with a switch statement is a [Duff's Device](http://en.wikipedia.org/wiki/Duff's_device). It's worth a look if you've never seen it. Essentially you interleave the body of the a loop with the body of the switch in order to unroll a loop while skipping some variable amount of the first iteration. – Apriori Apr 29 '14 at 19:52
2

C++03 certainly allows you to define variables within the body of a switch statement. That body is not at all different from any other compound statement, the rules for jumping to a label apply the same way: you can only jump into scope of

  • scalar types declared without initializers
  • class types with trivial default constructors and trivial destructors declared without initializers
  • arrays of the above

these rules didn't change in C++11.

#include <iostream>
int main()
{
    int n;
    std::cin >> n;

    switch(n)
    {
               int a;      // okay, scalar with no initializer
       case 1: int b = 10; // okay, no more labels, no way jump into scope
               a = b = 3*n;
               break;
    }
Cubbi
  • 46,567
  • 13
  • 103
  • 169
0

You can not write this because of scope problem. Your code will lead to a redefinition of the variable j

In your code :

const int i = ...
switch (i) { case 0: int j = 0; break; } // the error should be linked to default statement that is not there
switch (i) { case 0: { int j = 0; } break; } // here  you define a local scope in which you can define `j` ; j will be destroyed after the closing bracket.

Even in c++11, trying to do this :

switch (i) 
{ 
  case 0: int j = 0; break; 
  case 1: int j = 0; break; 
  case 2: int j = 0; break; 
} 

lead to the same error than if you want to write :

for ( ; ; ) {
      int i = 0 ;
      int i = 0 ;
      int i = 0 ;
}

That will lead to a redefinition error

leJon
  • 285
  • 4
  • 10
  • That is not the reason this is forbidden, see [this question](http://stackoverflow.com/questions/92396/why-cant-variables-be-declared-in-a-switch-statement) for the real reason (jumping over initialization). – rubenvb Apr 29 '14 at 18:20