Consider the following situation:
struct X { ... };
struct Y
{
Y(...);
...
X x;
...
}
X f()
{
...
if (...)
throw E;
...
}
Y::Y(...) :
... ,
x(f()) ,
...
{
...
}
Is there any undefined behaviour here? Are there any gotchas or potential problems with such a design when E is thrown?
Update:
Y::x may not be the only member variable of Y, may not be the first member variable in the class, and may be initialized half way through the Y::Y init list.
No. The construction of
Yis aborted.No
Yis ever created, so there is no destructor to call. Destructors for fully constructed elements, those declared beforexin the class body, will be called automatically (how would you otherwise know how far the initialization list you were when it throw). If you need to destroy anything, then you must catch the exception and destroy it yourself. You cannot absorb the exception, you can rethrow it, throw a new exception, or do nothing which will result in the exception being rethrown anyway. For your particular use case, there shouldn’t be anything to destroy since the constructor body is not going to be invoked at all.