I'm currently struggling with c++ and copy elision, specifically "named return value optimization" (NRVO), to be able to implement a factory-function pattern. I cannot obtain consistent behavior across different compilers. My mwe:
#include <iostream>
struct base {
virtual ~base() { std::cout << "dtor base\n"; }
};
struct derived : public base {
~derived() { std::cout << "dtor derived\n"; }
};
derived f() { return derived(); }
int main(int argc, char *argv[]) {
std::cout << "start\n";
new derived(f());
std::cout << "done. should have leaked!\n";
}
Note: Removing virtual base-dtor solves the problem, but I need it for my real implementation.
In case of gcc 5.4.0 the dtor is called, no copy elision is performed:
$ g++ test2.cpp && ./a.out
start
dtor derived
dtor base
done. should have leaked!
When using gcc 5.4.1 (Ubuntu calls it 5.4.1, I assume this is svn-head), all clangs I could get my hand on as well as various other gccs perform elision and successfully leak the memory:
$ g++ test2.cpp && ./a.out
start
done. should have leaked!
As I read the different places across the internetz, the compiler is allowed to do copy elision but not required. Only c++17 introduces guaranteed copy elision. So is this a bug in gcc 5.4.0, or is it just implementing the standard differently?