I was reading the documentation for std::for_each
here http://en.cppreference.com/w/cpp/algorithm/for_each and saw that the return value is std::move(f)
Why does the standard enforce moving the input parameter in the return value? Won't it be moved by default anyway, since the input parameter is passed by value?
This leads me to a couple of followups, when you compile the following code
Something function(Something something) {
return something;
}
The return statement is a move on my system with the highest optimization level (-O3
), why don't most compilers elide this return value? Local values are elided but function arguments are not..
Does C++17 enforce elision in this case? I read the proposal (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html) but I do not fully understand which cases qualify for mandatory elision.
I have tried this on Apple LLVM version 8.0.0 (clang-800.0.42.1)
on my Mac and on g++ 5.4
on Ubuntu 16.04.
This is due to a late-breaking change in the move-semantics rules for C++11. The original move proposal did not automatically move when by-value function arguments appeared on the return clause. However by late in the C++11 process, that language feature was added.
Prior to the language feature being added, for_each
"was moved". At that time the move on the return statement was necessary. But it became unnecessary, though harmless by the time C++11 shipped.
LWG issue 2747 corrected this for C++17.
As to your first followup question, I am not a compiler writer, but my best guess is: It is not currently legal to elide the return from a function parameter (that much I know), and I'm guessing as to why it isn't legal is that no one has figured out how to implement it, and thus no one has had the motivation to change the standard to make it legal.
Second follow up: No, C++17 does not enforce elision in this case. The rules remain the same as for C++11 in this case, save for the fact that the redundant move from for_each
is no longer specified.
From the comments below:
Why do you say it's not legal to elide the return from a function parameter?
I'm referencing N4660, which is C++17, but there is similar wording in C++98/03/11/14 ... backup, it has recently been protected. See N4659 instead (just as good):
15.8.3 Copy/move elision [class.copy.elision]
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, ...
- in a
return
statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function parameter or a variable introduced by the exception-declaration of a handler (18.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 call’s return object
This language specifically disallows elision from function parameters.
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