3
votes

This isn't a question on whether it's safe to throw an exception from a destructor.

http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9 states:

"During stack unwinding, all the local objects in all those stack frames are destructed. If one of those destructors throws an exception (say it throws a Bar object), the C++ runtime system is in a no-win situation: should it ignore the Bar and end up in the } catch (Foo e) { where it was originally headed? Should it ignore the Foo and look for a } catch (Bar e) { handler? There is no good answer — either choice loses information."

IE: if during stack unwinding another exception is thrown, then the runtime system is in a no-win situation because the catch handler to 'look for' is ambiguous.

Is there an 'exception' to the above, when the exception that is thrown during stack unwinding itself is in a try/catch block? In this case there is no ambiguity:

#include <iostream>
using namespace std;

class Component
{
public:
    ~Component()
    {
        cout << "In component destructor" << endl;
        try
        {
            throw 1;
        }
        catch (...)
        {
            cout << "Caught exception in component destructor" << endl;
        }
    }

};

class Container
{
public:
    ~Container()
    {
        cout << "In container destructor" << endl;
        Component component;
    }
}
    ;

int main()
{
    try
    {
        Container cont;
        throw 'a';
    }
    catch (...)
    {
        cout << "Caught main exception ok" << endl;
    }
return 0;
}

The following implies it, but I was wondering if anyone knew of the relevant C++ standard sections.

http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr155.htm

"If during stack unwinding a destructor throws an exception and that exception is not handled, the terminate() function is called. The following example demonstrates this:"

1

1 Answers

7
votes

Your Component destructor is safe. The rule you're quoting only applies if the exception is thrown out of the destructor (i.e., to the destructor's caller.)

EDIT: Here's one relevant quote from the standard (emphasis added)

Note: If a destructor called during stack unwinding exits with an exception, std::terminate is called (15.5.1).