Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a difference between an intermediate variable and return'ing a function call directly?

Tags:

c++

runtime

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;
}
like image 329
golazo Avatar asked Feb 13 '23 22:02

golazo


2 Answers

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.

like image 57
Eric Lippert Avatar answered Apr 26 '23 09:04

Eric Lippert


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.

like image 34
Maxim Egorushkin Avatar answered Apr 26 '23 09:04

Maxim Egorushkin