Jump to content

  • Log In with Google      Sign In   
  • Create Account


C++ and storage allocation questions


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 noatom   Members   -  Reputation: 769

Like
0Likes
Like

Posted 23 April 2013 - 02:56 PM

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, 23 April 2013 - 02:59 PM.


Sponsor:

#2 ApochPiQ   Moderators   -  Reputation: 14304

Like
0Likes
Like

Posted 23 April 2013 - 03:03 PM

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

#3 noatom   Members   -  Reputation: 769

Like
0Likes
Like

Posted 23 April 2013 - 03:10 PM

I initialized x,and still nothing.


Edited by noatom, 23 April 2013 - 05:31 PM.


#4 NightCreature83   Crossbones+   -  Reputation: 2674

Like
0Likes
Like

Posted 23 April 2013 - 03:33 PM

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, 23 April 2013 - 03:37 PM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#5 Brother Bob   Moderators   -  Reputation: 7786

Like
0Likes
Like

Posted 23 April 2013 - 04:08 PM

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.



#6 noatom   Members   -  Reputation: 769

Like
0Likes
Like

Posted 23 April 2013 - 05:31 PM

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






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS