views:

91

answers:

3

In the switch-case statements declaration-with-initialization is invalid but declaration-and-then-assignment is allowed. As shown in the following code snippet.

What is difference between these two type of initializations from the compiler side? And why is the first type of initialization invalid and second type a valid one.

switch(val)  
{  
case 0:  
  int newVal = 42;  //Invalid
  break;
case 1:  
  int newVal2;      //Valid
  newVal2 = 42;  
  break;
case 2:
  break;
}
+4  A: 

In fact, neither are legal C++. You cannot declare a variable in a switch case unless it is scoped:

switch(val)  
{  
case 0:  
  {
    int newVal = 42;  // now valid
  }
  break;
case 1:  
  {
    int newVal2;      // still Valid
    newVal2 = 42;  
  }
  break;
case 2:
  break;
}

The fact that your compiler permits case 1 is a defect of your compiler, or possibly an extension. At least, according to the standard.

John Dibling
The declaration of `int newVal2;` is valid because there is no initializer.
James McNellis
+1  A: 

This should help.

Chubsdad
+7  A: 

Effectively, the rule is that you can't jump into a block past a declaration that has an initialization (or past the declaration of a non-POD type variable). The C++ standard says (C++03 §6.7):

It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps(77) from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer (8.5).

(*) The transfer from the condition of a switch statement to a case label is considered a jump in this respect.

int newVal = 42; is a declaration that has an initializer (the = 42 part). The program is ill-formed because if val is 1 or 2, you'll jump into the switch block past the initialization.

int newVal2; is also a declaration; because int is a POD type and the declaration has no initializer, you can jump past this declaration.

James McNellis
+1: I was searching for this but could not locate in the Standard
Chubsdad
OK. It is so because the C++ Standard says so. But what is rational behind the same. Why does the standard says so. Isn't it strange that int newVal = 42; is not allowed where as int newVal; newVal = 42; is allowed?
Dahiya
@Dahiya: It's not that strange; initialization and assignment are different things (they are _very_ different things for most non-POD types, since constructors are then involved in initialization). Consider, for example, if you have a `std::string`; if you jump over its declaration, the variable is accessible but its contents are uninitialized because its constructor was never called.
James McNellis