#include <iostream>
usingnamespace std;
int anyfunction() { cout << "return 0" << endl; return 0;}
int main()
{
int x = 3;
constint y = 3;
constint z = 4;
switch(x)
{
case y:
int i=anyfunction(); //no brackets, so i must be available for case z
// case z:
// i=anyfunction(); //case z -> skips definition of "i"
// int i=anyfunction(); //case y -> redefinition of "i"
break;
}
return 0;
}
Because i is defined in case 'y' and there are no scope brackets, it must be available to the end of the switch statement. But this creates a paradox. In the case of 'z' if you skip case 'y' and try to use i, you use "i" before defining it. If you define "i" in case 'z', then case 'y' defines "i", falls through to 'z' where "i" is redefined. So the compiler is does not like that. If you place brackets around the statement(s) for case 'y' then there is no more confusion for the compiler.
1 2 3
case y:
{ int i=anyfunction();} //i only defined for case y
I am still learning C++ myself, so you will get some more feedback on this I'm sure.
This is a little silly for basic types like int (as in your example), but is a very critical bug/problem for objects. Since compilers tend to treat basic types like objects, you get the same error messages.
Here's an example of why this is bad with objects:
1 2 3 4 5 6 7 8 9
switch(foo)
{
case 0:
MyClass a(5); // ctor called here
break;
case 1:
break;
} // dtor called here
Notice that if the case 1 label is taken, the code will jump over the ctor, but will still call the dtor. Calling a dtor on an object that didn't have a ctor called is potentially disasterous, hence why you'd get an error in a situation like this.
A common solution is to localize the scope of the object:
1 2 3 4 5 6 7 8 9 10 11
switch(foo)
{
case 0:
{ // brace to localize scope
MyClass a(5); // ctor called here
} // dtor called here
break;
case 1:
break;
} // dtor no longer called here
But yeah -- this doesn't really apply to ints. So yeah it's a little strange. But in a way it makes sense.