Consider this code:
#include <iostream>
using namespace std;
struct Foo {
public:
int _a{};
Foo(int a) : _a{a}
{
std::cout << "ctor" << std::endl;
}
Foo(const Foo &)
{
std::cout << "copy" << std::endl;
}
};
int main () {
Foo a{10};
Foo b = 10;
std::cout << b._a << std::endl;
}
When I compile with
g++ -std=c++11 -fno-elide-constructors test.cpp
the output is
ctor ctor copy 0
which is what I expect, since the in Foo b = 10
, 10
is implicitly constructed from int
, then b
is copy constructed from Foo
. Furthermore, my copy constructor doesn't do anything, so the member _a
remains 0
(as it is in-class-initialized).
However, when I use copy elision
g++ -std=c++11 test.cpp
the output is
ctor ctor 10
which is surprising to say the least. I understand that the copy constructor is elided here, but this is a serious side-effect (the fact that the member is once initialized to 0 and once to 10), as it affects the rest of the code path.
Is this behaviour normal?