I do not understand the behavior of gcc here, I would expect RVO to apply, but regardless of whether I pass optimization flags and/or I pass -std=c++17
, in the second case, the gratuitous pair of braces seems to prevent GCC from eliding the copy.
$ cat /tmp/foo.cc
#include <iostream>
#define PING() std::cerr << __PRETTY_FUNCTION__ << '\n'
struct foo
{
foo() { PING(); }
~foo() { PING(); }
foo(const foo&) { PING(); }
};
foo bar()
{
PING();
foo res;
return res;
}
foo baz()
{
PING();
{
foo res;
return res;
}
}
int main()
{
foo f1 = bar();
foo f2 = baz();
}
$ g++-mp-7 -std=c++17 -O3 foo.cc
$ ./a.out
foo bar()
foo::foo()
foo baz()
foo::foo()
foo::foo(const foo&)
foo::~foo()
foo::~foo()
foo::~foo()
Shouldn't this be part of the guaranteed copy elision? The behavior of Clang matches my expectations:
$ clang++-mp-4.0 foo.cc
$ ./a.out
foo bar()
foo::foo()
foo baz()
foo::foo()
foo::~foo()
foo::~foo()