1

Q: Is it safe to throw and catch an exception on stack unwind, or does the application call terminate on the second throw?

minimal example:

void some_function()
{
    try
    {
        // do stuff here that can throw
        throw std::runtime_error("blah");
    } catch(const std::exception& re)
    {
        try // this code could be in some function called from here
        {
            // do something with re here that throws a logical_error
            throw std::logical_error("blah blah"); // does this call terminate?
        } catch(const std::logical_error& le)
        {
        }
    }
}

I got curious after reading this question.

Note: I know you can/should catch(...) in a destructor, but does it make sense in general to have a try/catch in a catch block - maybe in some function called on the exception (re in my example)?

Community
  • 1
  • 1
utnapistim
  • 26,809
  • 3
  • 46
  • 82

2 Answers2

4

That's not really during stack unwinding. Once a catch block is entered, the stack has already been unwound.

And yes, that code is legal. See this question: Nested try...catch inside C++ exception handler?

Community
  • 1
  • 1
Pubby
  • 51,882
  • 13
  • 139
  • 180
  • 1
    Conversely, throwing in a destructor **could** be "on stack unwind". And there's well-defined behavior specifically for that scenario. – Drew Dormann Mar 19 '13 at 19:24
  • 1
    +1. Yes, when it enters into `catch` block, there is no exception in the flight, which means the `catch` block can throw; the behavior is well-defined. In fact, rethrow (which is allowed from `catch` only) is one kind of throw. – Nawaz Mar 19 '13 at 19:26
3

Pubby's answer best answers the scenario you're describing.

As an addendum, while a stack is unwinding, the only user code that's executed is destructors (and the code those destructors call).

If you do throw in a destructor during this scenario (and don't catch the exception in the same destructor), the standard specifies that std::terminate() will be called.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • 1
    Not quite. If you throw an exception **that propagates out of the destructor** in this scenario the standard specifies that `std::terminate()` will be called. `try { throw 3; } catch(int) { }` inside a destructor won't lead to `std::terminate()`. – Pete Becker Mar 19 '13 at 21:00