问题
I'm trying to understand if there is any benefit to returning a const
reference. I have a factorial function that normally looks like this:
unsigned long factorial(unsigned long n)
{
return (n == 0) ? 1 : n * factorial(n - 1);
}
I'm assuming that there will be a performance increase when we pass by const
reference and we return a const
reference... but const
-correctness always confuses me.
const unsigned long & factorial(const unsigned long& n)
{
return (n == 0) ? 1 : n * factorial(n - 1);
}
Is it valid to return a const
reference? Furthermore, could somebody please tell me: is it beneficial?
回答1:
This is invalid. You can't return reference to a local variable.
MSVS C++ compiler even gives the following warning:
main.cc : warning C4172: returning address of local variable or temporary
Not quite sure about GCC, but probably the result would be the same.
回答2:
A const reference isn't faster than a value, if the size of the value is small. In this case the type of the value is long
, which is IMO small (e.g. 4 to 8 bytes): so a const reference will be no faster. In fact it may be slower, because to get the value of a reference the compiler may need to emit the code that will dereference the reference (like dereferencing a pointer).
Given that a reference is implemented (internally) like a pointer, I'd expect to get better performance from passing references than from passing values when the size of the value is bigger than the size of a pointer (assuming that it's even legal to pass a reference: a reference to a local variable that's gone out of scope isn't legal).
回答3:
The const reference is incorrect here - you're returning a reference to a local variable - an un-named temporary here, either 1
or the result of n * factorial(n - 1)
. Because the reference is to a local variable in the function, by the time the reference gets to the caller, that local variable has already gone out of scope, and is invalid.
Return a const reference to large structured types that you want to avoid a copy to when the reference will survive the exit of the function. Usually, this means returning a reference to an argument or to a member variable (in the case of classes).
回答4:
The only case where it is valid to return by const reference is if the object you are returning will outlive the function call* (such as returning a member of the class on which the function has been invoked), and even in that context, whether one should do that is dubious, since that will allow two different callers to access the same memory location, which makes things a nightmare to fix if you use multiple threads.
*NOTE: In your case, the item you are returning is a local variable and therefore will not outlive the function call. Hence the code you have provided is invoking the nefarious undefined behavior.
回答5:
Possible yet I'd never do that. Why?
Because this is a good way to make your code non-readable.
Additionally, the compiler will optimize it without this hack.
And additionally, don't you have other "bottlenecks" to optimize at your program?
I mean, if you take this portion of your code and look at it in assembly you'll see that passing the function the value and getting the result is merely a few opcodes. How?
Well, a 32bit integer will fit in a register. Quick as "mov eax, ...".
On the other hand, you program probably has other design/algorithm issues which might be optimized... Unless it's as simple as an "hello world" program.
So, getting down to this things isn't something I'd do, and everyone are welcome to challenge me.
来源:https://stackoverflow.com/questions/3216948/c-pass-by-const-reference-and-return-by-const-reference