Example:
struct s { int a; };
s func() { return {42}; }
int main() {
s new_obj = func(); // line 6
(void) new_obj;
return 0;
}
This works. Now, what happens, if we assume that our compiler does no RVO?
func
returns a struct of s
, so {42}
must be converted to s
, is then returned and finally copied to new_obj
in line 6.func
returns an initializer list, so a deep copy is impossible.What does the language say? Can you give a proof?
Note: I know that this does not seem useful in this example, but for returning very large, constant sized std::array
s, I do not want to rely on RVO.
Consider the following example:
#include <iostream>
struct foo {
foo(int) {}
foo(const foo&) { std::cout << "copy\n"; }
foo(foo&&) { std::cout << "move\n"; }
};
foo f() {
//return 42;
return { 42 };
}
int main() {
foo obj = f();
(void) obj;
}
When compiled with gcc 4.8.1 with -fno-elide-constructors
to prevent RVO the output is
move
If in f
the return statement without curly braces is used then, then the output is
move
move
With no RVO, what happens is the following. f
must create a temporary object of type foo
, let's call it ret
, to be returned.
If return { 42 };
is used, then ret
is direct initialized from the value 42
. So no copy/move constructor was called so far.
If return 42;
is used, then another temporary, let's call it tmp
is direct initialized from 42
and tmp
is moved to create ret
. Hence, one move constructor was called so far. (Notice that tmp
is an rvalue and foo
has a move constructor. If there was no move constructor, then the copy constructor would be called.)
Now ret
is an rvalue and is used to initialize obj
. Hence the move constuctor is called to move from ret
to obj
. (Again, in some circumstances, the copy constructor could be called instead.) Hence either one (for return { 42 };
) or two (for return 42;
) moves happen.
As I said in my comment to the OP's question, this post is very relevant: construction helper make_XYZ allowing RVO and type deduction even if XZY has noncopy constraint. Especially the excelent answer by R. Martinho Fernandes.
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