tags:

views:

150

answers:

7

Hi all,

Is it OK to return a reference to a local variable from a function? By local I mean that the variable would be created(on the stack i.e. without using new) within the function and its scope is within that function only. I got contradictory answers when I searched about this. 1) says that kind of usage is correct but 2) contradicts it.

1) http://functionx.com/cpp/examples/returnreference.htm
2) http://www.cprogramming.com/tutorial/references.html (under References & Safety section)

Which of them is right?

Another question I had is, if 1) is right then are the following serve same purpose.

i) int& a = func();
ii) int a = func(); where func() returns a reference to an int (local variable in that function).

In both the above cases, there is no copying of return value involved isn't it. I would like to prevent copying of return values since the return value could be large.

Thank you in advance.

Raghava.

+3  A: 

If you mean a variable internal to the function, no...it's always nonsense to return a reference to it. Returning a reference to a member variable from a member function is perfectly fine.

As to wishing to avoid copying large data structures. Please wait until you have actual profile data showing that you are a) actually making a copy, and b) that it's actually a bottleneck. "Premature optimization is the root of all evil," may be a bit extreme but premature optimization certainly causes a whole lot of pain and trouble while rarely, if ever, actually providing ANY of the benefits those attempts are meant to achieve.

Noah Roberts
@Noah: Yes, I meant a variable internal (local) to the function. I would edit my post to be more specific.
Raghava
+5  A: 

You can return a reference to a static local variable in a function. Otherwise, it is a recipe for disaster because the local variable is destroyed once the function returns.

Following may be helpful which takes the same example you cited in your first reference.

EDIT 2:

For point ii in your post, let us assume a function 'fn' as shown

int& fn(){
static int x;
return x;
}

int a = fn();

This involves a copy from the Lvalue of the expression 'fn'.

It does not involve a copy, if it was

int &a = fn();
Chubsdad
@chubsdad: Thank you for the link. It basically is the same question I asked here and even the poster there points to the same link that I mentioned.
Raghava
+1  A: 

It is never ok to return a reference to non-static local variable from a function. The variable goes out of scope when the function returns and thus the reference will refer to a destroyed object.

While this may appear to 'work' in the first example provided in 1), this bad practice will quickly begin to fail you with classes which have a destructor or are larger.

Its best to either return a pointer, return a reference to a local-static object, return a reference to a member variable.

In this case if the object is constructed inside the function to be returned, you might look into implementing C++ 0x move semantics on your large class. This would might be able to turn a 'large copy' into a few pointer swaps.

MerickOWA
By "return a pointer", I assume you mean a pointer to a dynamically allocated object. Returning a pointer to a local function variable has the exact same problem as returning a reference.
David Thornley
AND by "return a pointer", I assume you mean an RAII object *containing* a pointer. ;) As for implementing move semantics, I assume you mean IFF you observe copying actually occurring and also observe it causing a bottleneck.
Noah Roberts
@Noah: Copying would definitely occur if its a return by value right?
Raghava
@Raghava - In fact, no. See 12.8/15
Noah Roberts
@Noah: Thank u for the pointer. Later on, I would use a profiler and check if there is any performance penalty.
Raghava
+3  A: 

The examples that you see at your first link are totally bogus. That page at functionx.com is garbage. Returning a reference to a local (automatic) variable is always an error, since any attempts to access the returned value will result in undefined behavior.

The second link gets it right.

AndreyT
@Andrey: Thank you for the reply.
Raghava
+2  A: 

As everybody else is saying, don't do that. Returning a reference or pointer to a local variable is always wrong, because the act of returning gets rid of the local variable and hence the reference or pointer is automatically invalid.

Copying may not be an issue. C++ compilers are allowed to skip copy constructors when returning from functions (the "return value optimization"), so a sufficiently smart compiler might be able to build the value in place. Therefore, you may well be able to return a large value without any copying. Try it and see; you can temporarily put output statements in the copy constructor (if you've written one and aren't using the automatically generated one) to see if it's actually called.

So, without running and trying, you don't know whether there is actual copying going on, and if so how much of a problem it is. As always, time and profile a run to see if there is a problem and, if so, where. Doing anything risky and/or confusing to speed up performance is almost never worth doing before timing and profiling.

David Thornley
+1  A: 

definitely not right to return a reference to a local variable stored in the stack. When you call other functions that area of memory will be overwritten and you will get stack corruption if you try to write to that variable

lurscher
A: 

assuming that func returns a reference to a value that lives after the function return (static local, or global) then your

i) int& a = func();
ii) int a = func(); where func() returns a reference to an int (local variable in that function).

are quite different

in (i) a still refers to the static or global. Chaning a will change the original variable

in (ii) a is a local copy, changing it has no effect on the original variable

pm100