What Are the Signs of Crosses Initialization

What are the signs of crosses initialization?

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 read int 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.

switch(i)
{
case 1:
{
int r = 1;
cout << r;
}
break;
case 2:
{
int r = x - y;
cout << r;
}
break;
};

The Standard says (6.7/3):

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 (3.9) and is declared without an initializer (8.5).

Getting a bunch of crosses initialization error

The C++ standard says:

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 (3.9) and is declared without an initializer.

The cases in switch are considered as a "jump".

Just put all objects and variables initializations before your switch, and everything will be fine.

Consider this code:

switch(k)
{
case 1:
int t = 4;
break;
default:
break;
}

It will cause a "crosses initialization" error, because it is possible to skip the initialization of t, but after that it will still be in scope, even though it was never created in the first place.

Now consider this:

switch(k)
{
case 1:
{
int t = 4;
}
break;
default:
break;
}

Here, you will not have the error, because the variable is inside a block, and will die at the end of the block ( at the closing { ), so after that it will not be in scope in any case.

To fix the first case, you just need to do:

int t = 0;
switch(k)
{
case 1:
t = 4;
break;
default:
break;
}

Overkilling crosses initialization of variable error in C++?

There is nothing wrong with the compilers. Your code is ill-formed according to the standard.

In your particular case, the requirement of the standard may not be necessary and the jump could be allowed and the compiler could create valid code. However, this is only because the initialisation of the variable int i has no side effects.

You can make your code valid by simply enclosing the jumped section in its own scope:

#include <cstdlib>

int main ()
{
goto end;
{
int i = 0; // unused variable declaration
}
end:
// cannot use i here, as it's not defined.
return EXIT_SUCCESS;
}

C++ cross initiialization error

The compiler is correct: C++ does not allow you to skip over a variable declaration in the same scope. goto is similarly restricted.

If you need SaveLogin for all cases then declare it above the switch. If you only need it for case 2 then use scope blocks:

case 2 /*not directly relevant but there's no need for the parentheses*/:
{
// register
ofstream SaveLogin; /*ToDo - more logic here unless it's contained
fully within construction and destruction*/
break;
}
case 3:

Error: Jump to case label in switch statement

The problem is that variables declared in one case are still visible in the subsequent cases unless an explicit { } block is used, but they will not be initialized because the initialization code belongs to another case.

In the following code, if foo equals 1, everything is ok, but if it equals 2, we'll accidentally use the i variable which does exist but probably contains garbage.

switch(foo) {
case 1:
int i = 42; // i exists all the way to the end of the switch
dostuff(i);
break;
case 2:
dostuff(i*2); // i is *also* in scope here, but is not initialized!
}

Wrapping the case in an explicit block solves the problem:

switch(foo) {
case 1:
{
int i = 42; // i only exists within the { }
dostuff(i);
break;
}
case 2:
dostuff(123); // Now you cannot use i accidentally
}

Edit

To further elaborate, switch statements are just a particularly fancy kind of a goto. Here's an analoguous piece of code exhibiting the same issue but using a goto instead of a switch:

int main() {
if(rand() % 2) // Toss a coin
goto end;

int i = 42;

end:
// We either skipped the declaration of i or not,
// but either way the variable i exists here, because
// variable scopes are resolved at compile time.
// Whether the *initialization* code was run, though,
// depends on whether rand returned 0 or 1.
std::cout << i;
}


Related Topics



Leave a reply



Submit