Anas Ouardini
Anas Ouardini

Reputation: 49

goto produces an error "bypassing initialization"

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.

Upvotes: -3

Views: 1062

Answers (3)

xyrix
xyrix

Reputation: 51

You can disable this behaviour in MSVC by giving the compiler flag /Zc:gotoScope-, you can also disable the warnings that are generated when jumping over trivial variable initialisation with the compiler flag /wd4533.

Relevant links:

Upvotes: 0

Erciyuanshagou
Erciyuanshagou

Reputation: 26

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.

Upvotes: 1

eerorika
eerorika

Reputation: 238431

I think this should not throw an error at all

The compiler is free to refuse to compile ill-formed programs.

Is there any solution to this

Solutions:

  1. Don't initialise a.
  2. Declare a before the jump.
  3. Declare a after the label.
  4. Don't use the goto (my favourite).
  5. Limit the scope of a by declaring it within a block statement that ends before the label.

Upvotes: 3

Related Questions