Consider following code:
#include <iostream>
using namespace std;
int main()
{
int x, y, i;
cin >> x >> y >> i;
switch(i) {
case 1:
// int r = x + y; -- OK
int r = 1; // Failed to Compile
cout << r;
break;
case 2:
r = x - y;
cout << r;
break;
};
}
G++ complains crosses initialization of 'int r'
.My questions are:
- What is
crosses initialization
? - Why do the first initializer
x + y
pass the compilation,but the later failed? - What are the problems of so-called
crosses initialization
?
EDIT:
I know I should use brackets to specify the scope of r
but I want to know why,for example why non-POD could not be defined in multi-case switch statement.
Thanks.
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps 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 and is declared without an initializer.
The transfer from the condition of a switch statement to a case label is considered a jump in this respect.
You should put the contents of the
case
in brackets to give it scope, that way you can declare local variables inside it:I suggest you promote your
r
variable before theswitch
statement. If you want to use a variable across thecase
blocks, (or the same variable name but different usages), define it before the switch statement:One of the benefits is that the compiler does not have to perform local allocation (a.k.a. pushing onto the stack) in each
case
block.A drawback to this approach is when cases "fall" into other cases (i.e. without using
break
), as the variable will have a previous value.The version with
int r = x + y;
won't compile either.The problem is that it is possible for
r
to come to scope without its initializer being executed. The code would compile fine if you removed the initializer completely (i.e. the line would readint r;
).The best thing you can do is to limit the scope of the variable. That way you'll satisfy both the compiler and the reader.
The Standard says (6.7/3):