Is it ALWAYS safe to return temporary variables ?

This is a discussion on Is it ALWAYS safe to return temporary variables ? within the C++ Programming forums, part of the General Programming Boards category; Is it always safe to return temporary stack variables from a function as long as you don't return a reference ...

Is it ALWAYS safe to return temporary variables ?

Is it always safe to return temporary stack variables from a function as long as you don't return a reference or a pointer ? So is this always gauranteed to be safe, on all platforms/compilers/targets ? The compiler is never going to generate ASM that uses the location of testA in an unsafe manner ? (e.g. a location on the stack that is trashed when getA() returns)

>but someone just pointed this out at a potential bug.
Who told you that, and what proof do they have?

They don't... But then I don't have any proof to the contrary :-) I've alway ASSUMED that this was safe (that compiler was gauranted to copy the returned variable before the stack was popped), and its never failed for me, but I never really thought about it. He recon'ed it would usually be the case if the variable was small, but if it was big the generate ASM could potentially pass the reference to the location on the stack (which would *usually* work, but could conceiably get corrupted before it was used).

The point is I know it usually (i.e. in all the cases I've ever done it) works, but is it GAURANTEED to work no matter what compiler and what H/W.

>but is it GAURANTEED to work no matter what compiler and what H/W.
For a conforming compiler, absolutely. Unfortunately, we can't make blanket claims about non-conforming compilers. However, these semantics have been in place since before C, so any compiler that fails to make that guarantee while claiming to implement C++ is severely broken.

There is one situation, and that is when the local object itself holds a reference to another local object and its copy constructor does not copy that object. In that case, the same caveats as with returning temporaries apply.

As CorndBee alluded, one case where this isn't necessarily true is if the class type contains a pointer or reference type. In practice, the implicitly generated constructor may not do this correctly (as it effectively does a bitwise copy of the value of pointers and references, which may not make sense for the class). If the programmer forgets to explicitly provide a copy constructor and/or assignment operator for the class in this case, returning an object of that type from a function (which logically invokes the copy constructor) or assigning the value to a variable (which logically invokes the assignment operator or copy constructor) can yield undefined or other spurious behaviours.

For example, this causes both a memory leak and undefined behaviour as main() returns.

The above ignores compiler optimisation. Things get a little more complicated, as compilers are allowed to -- but not required to -- eliminate some calls of constructors in some instances involving temporaries (and returning a value from a function is once such instance => the return value optimisation). Such things virtually guarantee that the code above will function differently between compilers and even compiler/optimiser settings for a particular compiler (even if we ignore the presence of undefined behaviour as main() returns).

>That's not necessarily true.
I think you missed this part of Mario's post:
>or explicit copy constructor

No I did not. I just used an example with an implicitly generated copy constructor.

Having an explicit copy constructor is not the same thing as making that copy constructor behave correctly for all usage patterns. There is no way to force a programmer (other than embarrassment and other non-technical means) to write a copy constructor that does what the user of the class expects.

The claim that the compiler is not GAURANTEED to pass a copy of the return value, is essentially FALSE. As far as the compiler is concerned this is ALWAYS okay. It may not necessarily copy the return value if it performs NRVO, but the effect is the same and is always legal.

The only issue comes from bugs that the programmer of the class [being copied on return] has made.
For example not following the http://cpp.codenewbie.com/articles/c...ee-Page_1.html "rule of three" as necessary.
Or if the class should not be copyable, but it does not contain a private copy-constructor preventing this.

If the class is 'broken' in one of these ways, then the bug lies there.

The usage rules are provided by the class implementer and exposed through the interface. The user of the class has no other choice than to follow these rules, derive, or create his own implementation.

Of course, bugs in the implementation of the class will render it... useless for the most part. And needless to say that an explicit and conscious negation of a suitable copy constructor and assignment operator will not allow the example the OP provided. But that type of implementation, again, is exposed through the interface. The user must know how to interpret the class usage.

But all things equal, and that is what I believe the point of the OP was, there is nothing wrong or "bugable" in returning an object by value.

We could probably waste a few good forum pages discussing situations where this would not be possible. None of them though would negate the previous paragraph.

But all things equal, and that is what I believe the point of the OP was, there is nothing wrong or "bugable" in returning an object by value.

Quite.. I realized there inumerable ways for you to break code that returns in this way (e.g. if testA was storing a reference to another temporary object on the stack). But that wasn't point of OP, I was asking that if you don't do any craziness with pointers or references inside of getA() or in the class itself, is that still a potentially unsafe operation.