question on function returning a reference in C++
Is it OK to return a reference to a local variable from a function? By local I 开发者_JAVA技巧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.
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.
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();
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.
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.
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.
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
精彩评论