Sign in to follow this  

C++ and storage allocation questions

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites

I initialized x,and still nothing.

Edited by noatom

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this