1
class D { public: ~D() { throw std::exception(); } }; int main() { try { try { D d; } catch (...) { cout << "1"; } } catch (std::exception& e) { cout << "2"; } } 

My understating is that this should be caught in 2. But its not caught, and instead program is terminated.

4
  • The exception is caught in 1 and not rethrown up to 2 Commented Aug 12, 2019 at 16:04
  • @Madden have you tried? i have tried, it does not work as you said. And it should not happen in 1. Commented Aug 12, 2019 at 16:07
  • 5
    A throwing destructor needs to be declared as noexcept(false) since C++11 see: en.cppreference.com/w/cpp/language/destructor "...Thus a throwing destructor must be explicitly declared noexcept(false)..." Commented Aug 12, 2019 at 16:08
  • 3
    Please don't throw from destructors.. Commented Aug 12, 2019 at 16:15

1 Answer 1

7

In C++11, destructors are implicitly noexcept, so std::terminate is called automatically if the destructor throws an exception that isn't caught within the destructor itself.

Even before that, destructors that throw an uncaught exception during stack unwinding cause std::terminate to be invoked, so what you're doing won't work if the destructor is invoked by some other exception bubbling up the stack.

If that's not a concern, you can explicitly declare your destructor to be ~D() noexcept(false) (which would allow exceptions to bubble out of the destructor if the destructor wasn't triggered by some other exception causing stack unwinding).

Note that even though it's technically legal, it's generally considered a bad idea to throw uncaught exceptions in a destructor, since it makes your class largely unusable in any context where a handleable exception might be thrown. You can read more at c++ exception in destructor (which isn't a strict duplicate, but covers your scenario completely).

Sign up to request clarification or add additional context in comments.

7 Comments

Note that the destructor of D is not called during stack unwinding in the OP's example.
@Brian why its not called?
@henryyao The destructor is called but stack unwinding only starts after the destructor throws. At that point, there are no more objects to destroy.
@Brian Isn't stack unwinding process calls destructors?
@henryyao -- "stack unwinding" refers to the cleanup that's done when an exception has been thrown and is caught by a catch clause higher up. It's not about ordinary cleanup, which invokes destructors at the end of a block. The issue is what should happen when an exception is being processed and during that processing another exception is thrown.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.