1

This question is related to Function returning value vs modifying value passed by reference. I want to know if gcc will optimize the following the same way. Imagine the two functions do the same thing:

Return:

vector<int> f(...)
{
    vector<int> r;
    ...
    return r;
}

Pass by reference:

void f(vector<int> &r, ...)
{
    ...
}

vector<int> r;
f(r, ...)

Pass by reference occurs frequently in (performance critical) GMP functions.

Community
  • 1
  • 1
qwr
  • 9,525
  • 5
  • 58
  • 102
  • Depends on what `...` is. Note that the pass-by-reference case may implicate aliasing considerations. – T.C. Nov 27 '15 at 23:32
  • Typically, the compiler will do return value optimisation (or corresponding move type operation). But it does depend on lots of circumstances that makes a small difference each. – Mats Petersson Nov 27 '15 at 23:34
  • It could depend on the usage as well. For example if `r` is large, and `f()` is called in a loop, you have to be careful to avoid completely deallocating and reallocating the vector contents each iteration. (i.e. re-using the existing capacity is ideal) – M.M Nov 27 '15 at 23:50
  • @T.C. what aliasing considerations? – M.M Nov 27 '15 at 23:51
  • 2
    @M.M It's harder for the compiler to prove that some external pointer you write to or some external function you call won't change the passed-by-reference vector. – T.C. Nov 28 '15 at 09:41

1 Answers1

0

Generally compilers are not obligated to do NRVO (Named Return Value Optimization) aka copy elision even if the certain criteria that allow it are met. Nor a program must be depended on such optimizations as it makes it effectively non portable.

Now, as far as it concerns the first case, the answer is yes, the compiler is permitted to optimize away the copy of the vector. In particular this case falls in the following wording of the standard 12.8/p31.1 Copying and moving class objects [class.copy]:

... elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):

(31.1) — in a return statement in a function with a class return type, when the expression is the name of a nonvolatile automatic object (other than a function parameter or a variable introduced by the exceptiondeclaration of a handler (15.3)) with the same type (ignoring cv-qualification) as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value.

Also, from C++11 and beyond std::vector has move facilities and actually the vector is going to be moved.

As far as it concerns the second case the answer is no. And after all there's no need to, since you pass a reference to the vector. That is, you pass an alias of the vector (i.e. the object itself).

101010
  • 41,839
  • 11
  • 94
  • 168