# C++ and storage allocation questions

This topic is 1731 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

According to one of my books,the following code should not work:

void f(){
int ma;
cin >> ma;
if(ma == 10)
goto heya;

int x;
heya:
cout << "a";
}


Why? Because the storage for x is allocated at the beginning of the code block,but if I type 10,then it will jump to heya,so,it will skip the definition,thus constructor call.

The code should generate a warning,or an error,but I got none.

The code + explanation is from Thinking in C++.

Is that concept still correct,or outdated?

Edited by noatom

##### Share on other sites
The concept is fine, but the specifics are a bit off. Try initializing x - that should generate a warning.

##### Share on other sites

I initialized x,and still nothing.

Edited by noatom

##### Share on other sites
What level are you compiling this at because if any optimisations are on the compiler will just ignore the declaration of "x" as it can tell you are never going to use it. And even then the CPU can shift all of these instructions around if it likes so there is no way to say for certain it won't just initialise x at the beginning of the function or even at all.

All you will get when initialising the parameter is a initialised but unused variable detected warning which is what I expected anyway, and that is in a debug build with no optimisations on btw.

A compiler is allowed to change your code as long as the instruction that make it into the executable have the same behaviour as what you expressed in the code. So it is very likely you are just running into a compiler transformation that makes the code more efficient to execute. If you are interested in knowing more about these kind of transformations you should watch this as it explains what the compiler and CPU are allowed to do in the face of multithreading and it's barriers(semaphore, mutex, critical section): http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2 Edited by NightCreature83

##### Share on other sites

What level are you compiling this at because if any optimisations are on the compiler will just ignore the declaration of "x" as it can tell you are never going to use it. And even then the CPU can shift all of these instructions around if it likes so there is no way to say for certain it won't just initialise x at the beginning of the function or even at all.

All you will get when initialising the parameter is a initialised but unused variable detected warning which is what I expected anyway, and that is in a debug build with no optimisations on btw.

A compiler is allowed to change your code as long as the instruction that make it into the executable have the same behaviour as what you expressed in the code. So it is very likely you are just running into a compiler transformation that makes the code more efficient to execute. If you are interested in knowing more about these kind of transformations you should watch this as it explains what the compiler and CPU are allowed to do in the face of multithreading and it's barriers(semaphore, mutex, critical section): http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2

There's more to it than just preserving the observed behavior; it has to compile with respect to rules defined by the language. Any optimization, such as removing unused variables, has to be performed at a later stage.

For example, the language states that it is illegal to jump past an initialization. And, if you use Visual Studio and disable language extensions (VS allows jumping past initialization by default, it has to be explicitly disabled), then the compiler indeed generates an error saying that the jump skips initialization of the variable. Without initialization, the jump is fine according to the language and the compiler doesn't complain. So the error is generated, because that is how the language is defined, even if the variable is unused and will be removed at a later optimization stage.

##### Share on other sites
class X {
public:
X();
};

X::X() {}

void f(int i) {

if(i < 10) {
//! goto jump1; // Error: goto bypasses init
}
X x1; // Constructor called here
jump1:

switch(i) {
case 1 :
X x2; // Constructor called here
break;

//! case 2 : // Error: case bypasses init
X x3; // Constructor called here
break;
}
}


In the code above, both the gotoand the switchcan potentially jump past the sequence point where a constructor is called. That object will then be in scope even if the constructor hasn’t been called, so the compiler gives an error message. This once again guarantees that an object cannot be created unless it is also initialized