I'm trying to use labels in my project but when I jump over a set of instructions using goto to transfer control to another section of the code, I get this error that says: transfer control bypasses initialization of (certain variables).
This is the code that produces the error:
goto label1;
label00:
int a = 0;//the compiler can't let me skip this line
int b; // but this line is fine to skip over
b = 0; //because i initialize it here instead of doing it like the a variable
label1:
//other instructions
as you can see I have two variables initialized but one of them is defined then initialized but the other one is defined and initialized at the same line.
The one that is defined and initialized at the same line variable a does not produce an error when skipped over, but the other one does.
I'm using VS2019 to compile this code. I think this should not throw an error at all and the compiler should give you a warning so that you know you're skipping something in both cases a and b initializations.
Is there any solution to this like disabling something in the settings?
I don't want to declare my variables then initialized them when using labels.
The example variables used in the question are int
, so the problem is not obvious. But you can easily notice why this is not allowed if you change int
to something not trivially destructible.
Consider this code:
#include<string>
int main() {
goto label_bypass;
std::string str("gibberish");
label_bypass:
return 0;
}
When the function is about to return, it must destroy all its stack variables including str
. By calling str
's destructor, it tries to deallocate the string buffer of str
. However, since str
's initialization is bypassed, the buffer was never allocated. The buffer's pointer may well be pointing to a random address. Segmentation fault! You may also want the compiler to be clever enough to decide whether to call the destructor when it unstacks, but this would become nigh impossible if the program grows complex enough. So c++ chooses to prohibit jumping over initializations altogether.
As in the case of int b; b = 0;
, since int
is a primary type, int b
can be considered an uninitialized declaration, and b = 0
is an assignment. They are both allowed to be jumped over.