c++c++11gccclang

Copy elision possible if returning parameter?


Consider a function that takes an object by value, performs some operations on it and return that object, for example:

std::string MyToUpper (std::string s)
{
      std::transform(s.begin(), s.end(), s.begin(), std::toupper);
      return s;
}

Now you call this function with a temporary:

std::string Myupperstring = MyToUpper("text");

Conceptually there is no copy needed. Are modern Compilers able to elide all copies in this case? If not, are there only moves? What about this case:

std::string Mylowerstring("text");
std::string Myupperstring = MyToUpper(std::move(Mylowerstring));

Solution

  • At most one of the two conceptual copies can be elided. If you pass a temporary to the function, then that copy can be elided, per the third bullet of C++11 12.8/31:

    when a temporary class object ... would be copied/moved ..., the copy/move operation can be omitted

    The return can't be elided; that can only be done for temporaries (per the rule quoted above) or local variables, per the first bullet:

    in a return statement ... when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) ... the copy/move operation can be omitted

    In the absence of elision, return values are treated as rvalues and moved if possible (and it is possible here); function arguments are moved if they are rvalues, as they are in both your examples.