C++ says “We have try at home”

Published: (December 28, 2025 at 01:42 AM EST)
2 min read

Source: Hacker News

Finally in other languages

Many languages¹ that have exceptions also have a finally clause, so you can write

try {
    // stuff
} finally {
    always();
}

A quick check shows that this control structure exists in Java, C#, Python, JavaScript, but not in C++.

C++ approach

C++ says, “We have try…finally at home.”
In C++, the way to get a block of code to execute when control leaves a block is to put it in a destructor, because destructors run when control leaves a block. This is the trick used by the Windows Implementation Library’s wil::scope_exit function: the lambda you provide is placed inside a custom object whose destructor runs the lambda.

auto ensure_cleanup = wil::scope_exit([&] { always(); });

/* stuff */

Exception‑handling quirks

Although the principle is the same, each language treats the case where the finally (or destructor) itself throws an exception slightly differently.

No exception in the guarded block

If control leaves the guarded block without an exception, then any uncaught exception that occurs in the finally block or the destructor is thrown from the try block. All the languages seem to agree on this.

Exception in both the guarded block and the finally/destructor

LanguageBehavior when both the guarded block and the finally/destructor throw
Java, C#, Python, JavaScriptThe exception thrown from the finally block overwrites the original exception; the original exception is lost. Update: Python 3.2 now saves the original exception as the context of the new exception, but the new exception is still the one that propagates.
C++An exception thrown from a destructor terminates the program if the destructor is running because of another exception.²

So C++ gives you the ability to run code when control leaves a scope, but your code had better not allow an exception to escape if you know what’s good for you.

Footnotes

  1. The Microsoft compiler also supports the __try and __finally keywords for Structured Exception Handling. These are intended for C code. Don’t use them in C++ code because they interact with C++ exceptions in sometimes‑confusing ways.
  2. This is why wil::scope_exit documents that it will terminate the process if the lambda throws an exception. There is an alternate function wil::scope_exit_log that logs and then ignores exceptions thrown from the lambda. There is no variation that gives you Java‑like behavior.
Back to Blog

Related posts

Read more »

C++ says 'We have try at home.'

Many languages¹ that have exceptions also have a finally clause, so you can write: cpp try { // ⟦ stuff ⟧ } finally { always; } A quick check shows that this co...