Reference: Copy Elision
Excerpts:
Under the following circumstances, the compilers are permitted, but not required to omit the copy and move (since C++11) construction of class objects even if the copy/move (since C++11) constructor and the destructor have observable side-effects.
In a catch clause, when the argument is of the same type (ignoring cv-qualification) as the exception object thrown, the copy of the exception object is omitted and the body of the catch clause accesses the exception object directly, as if caught by reference (there cannot be a move from the exception object because it is always an lvalue).
Given this premise, will the first catch clause also result in copy-elision? Or will only the second result in copy-elision?
uniquePtrObj makeObj(type args){
uniquePtrObj = make_unique<obj>(args);//depending on memory required, this could
//result in bad_alloc being thrown
return uniquePtrObj;
}
int main (){
try{
uniquePtrObj = makeObj(type args);//allocates heap memory
}catch(std::exception e){}//will this also result in copy-elision?
}catch(std::bad_alloc e){}//or only this will result in copy-elision?
return 0;
}
TIA
As the excerpt indicates, this form of copy elision can only occur when the object declared by the catch clause has the same type as the exception object, other than top-level cv-qualification. In the first catch clause, the type caught is a base class of the exception object's class, so copy elision cannot occur.
To see why copy elision isn't allowed in such cases, consider the general case of
try {
throw Derived ();
} catch (Base b) {
b.virtualFunction();
}
As written, this requires slicing to occur (whether the programmer intended it or not): the derived class's overrider of the virtual function can't be called, because the programmer requested the creation of an independent, complete Base
object (not a reference to the Base
part of a possibly derived object). If the compiler decided to elide the copy by making b
into a reference, the behaviour would change because the overriding function in Derived
would get called.