Is there any difference between calling a function in return and calling the function and then returning the value on runtime, like this:
my functions prototypes:
int aFunc(int...);
int bFunc(int...);
my first bFunc return line:
int bFunc(int...)
{
...
return (aFunc(x,...));
}
my second bFunc return line:
int bFunc(int...)
{
...
int retVal = aFunc(x,...);
return retVal;
}
To answer your specific question: there should not be an observable difference between
return expression;
and
x = expression;
return x;
provided of course that x
is of the correct type.
However, in C++ there can be a difference between
return complicated_expression;
and
x = some_subexpression;
y = some_other_subexpression;
return complicated_expression_rewritten_in_terms_of_x_and_y;
The reason being: C++ guarantees that destructors of temporary values created during the evaluation of a subexpression are run at the end of the statement. This refactoring moves the side effect of any temporary value destructor associated with some_expression
from after the computation of some_other_subexpression
-- at the end of the return
statement - to before it - at the end of the assignment to x
.
I have seen real-world production code where this refactoring introduced a bug into the program: the computation of some_other_subexpression
depended for its correctness on the side effect of the destructor of a temporary value generated during the evaluation of some_subexpression
running afterwards. The rewritten code was easier to read, but unfortunately also wrong.
There may be a difference if the return type is something more complex like std::vector
, depending on the optimizations implemented in the compiler.
Returning an unnamed vector requires (anonymous) return value optimization to avoid a copy, a common optimization. Whereas returning a named value requires named return value optimization, something not all compilers did in the past:
The Visual C++ 8.0 compiler ... adds a new feature: Named Return Value Optimization (NRVO). NRVO eliminates the copy constructor and destructor of a stack-based return value. This optimizes out the redundant copy constructor and destructor calls and thus improves overall performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With