From the related c++ standard section :
Referring to any non-static member or base class of an object in the handler for a function-try-block of a constructor or destructor for that object results in undefined behavior.
eg.
T::~T()
{
try {
this->nonstatic_member; // iff I read the quote correctly
} catch( ... ) {
}
}
So why is this undefined behaviour ?
I think the reason why accessing non-static data members in a function-try-block of a destructor is that [except.ctor]/2 and [except.handle]/11 guarantee that all subobjects have already been destroyed when entering the catch-clause of said try-block:
github draft from 2014-07-23, [except.ctor]/2
An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects (excluding the variant members of a union-like class), that is, for subobjects for which the principal constructor has completed execution and the destructor has not yet begin execution.
[except.handle]/11
[...] The base classes and non-variant members of an object shall be destroyed before entering the handler of a function-try-block of a destructor for that object.
Therefore, whether we throw the exception in the dtor of the class itself, or in the dtor of a subobject: all subobjects will be destroyed.
#include <iostream>
struct loud
{
~loud() { std::cout << "~loud()\n"; }
};
struct T
{
loud l;
~T() noexcept(false)
try
{
std::cout << "throwing an int\n";
throw 42;
}catch(int)
{
std::cout << "caught an int\n";
throw;
}
};
int main()
{
try
{
T t;
}catch(...)
{
std::cout << "caught an exception in main\n";
}
}
Output:
throwing an int ~loud() caught an int caught an exception in main
Live example
#include <iostream>
struct loud
{
loud() { std::cout << "loud()\n"; }
~loud() { std::cout << "~loud()\n"; }
};
struct A
{
A() { std::cout << "A()\n"; }
~A() noexcept(false) { std::cout << "~A()\n"; throw 42; }
};
struct T
{
loud l;
A a;
~T() noexcept(false)
try
{
}catch(int)
{
std::cout << "caught an int\n";
throw;
}
};
int main()
{
try
{
T t;
}catch(...)
{
std::cout << "caught an exception in main\n";
}
}
Output:
loud() A() ~A() ~loud() caught an int caught an exception in main
Live example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With