What happens when a destructor throws

The surprise in interviews
It has been reported that many developers — even candidates for senior roles — trip over a deceptively simple C++ question: what happens when a destructor throws? It’s an interview litmus test that reveals whether someone understands not just syntax, but the story behind RAII and stack unwinding. Why does this matter? Because RAII is how C++ keeps resources honest when things go wrong; if you don’t know how destructors behave, you can accidentally turn a cleanup into a hard crash.
The standard’s blunt answer
Since C++11, destructors are implicitly noexcept(true) unless you explicitly declare otherwise (or a base/member destructor can throw). That matters: if a destructor lets an exception escape while it’s marked noexcept, the program calls std::terminate. If you explicitly write ~T() noexcept(false), the destructor can throw and its exception will propagate normally — but there’s a critical caveat. If a destructor throws while stack unwinding is already in progress because of a different exception, the runtime calls std::terminate immediately. Two simultaneous exceptions during unwinding? Game over. Short version: throwing from a destructor is allowed only with care, and during unwinding it’s fatal.
Practical takeaways
So what should you do? Don’t throw from destructors. Prefer logging, storing error state, or exposing an explicit close() or release() method that returns errors rather than relying on the destructor. If you must attempt something that can fail in a destructor, guard it with checks like std::uncaught_exceptions (or otherwise ensure you won’t throw during unwinding) and keep the destructor noexcept. It’s less glamorous than dramatic exception-based cleanup, but it keeps your program from turning a recoverable error into an abrupt termination — and that, in the end, is the whole point of careful resource management.
Sources: sandordargo.com, Hacker News
Comments