After reading about copy elision of cppreference I wanted to play with exceptions and copy elision. So I wrote the following code with gcc 7.2 on coliru
#include <iostream>
class Exception
{
public:
Exception() { std::cout << "constructed\n"; }
Exception(Exception& other) {std::cout << "copy constructed\n";}
Exception(const Exception& other) {std::cout << "copy constructed\n";}
Exception(Exception&& other) {std::cout << "move constructed\n";}
};
void foo()
{
throw Exception();
}
int main()
{
try
{
foo();
}
catch(Exception e )
{
}
}
Output
constructed
copy constructed
We can see that the copy constructor is called and this happens even when gcc is invoked with -O2. It seems to me that this code should be eligible to copy elision according to the following clause :
When handling an exception, if the argument of the catch clause is of the same type (ignoring top-level cv-qualification) as the exception object thrown, the copy is omitted and the body of the catch clause accesses the exception object directly, as if caught by reference.
So why is the copy constructor called? Why does copy elision not work in this case?