TL;DR
Many modern languages offer a finally clause to run cleanup when control leaves a block; C++ provides the same effect via destructors and RAII. That approach works but has different exception semantics — notably, a destructor that throws during stack unwinding will terminate the program.
What happened
Raymond Chen's Dev Blog post contrasts the explicit try…finally construct found in languages such as Java, C#, Python and JavaScript with the C++ approach. C++ does not include a dedicated finally keyword; instead, developers rely on destructors and RAII to run code when a scope is exited. Libraries like the Windows Implementation Library (wil) expose helpers such as wil::scope_exit that store a lambda in an object whose destructor invokes the cleanup action when the object goes out of scope. The post then highlights divergent behaviors when cleanup code itself raises an exception: if no prior exception exists, any exception from finally/destructor is propagated; but if an exception is already propagating, languages differ — many replace the original exception with the new one while C++ will abort if a destructor throws during stack unwinding. Microsoft also provides __try/__finally for C, but the blog cautions against using that in C++.
Why it matters
- C++ developers achieve deterministic cleanup without a finally keyword by leveraging destructors and RAII.
- Exception-handling semantics differ across languages; relying on destructor-based cleanup requires care to avoid terminating the process during stack unwinding.
- Library choices (e.g., wil::scope_exit vs wil::scope_exit_log) affect how cleanup exceptions are handled in C++ code.
- Mixing structured-exception keywords intended for C with C++ exceptions can produce confusing interactions; the Microsoft __try/__finally is intended for C only.
Key facts
- Languages with a finally clause mentioned: Java, C#, Python, JavaScript.
- C++ has no built-in try…finally construct; destructors run when control leaves a scope and are used for cleanup instead.
- wil::scope_exit places the provided lambda inside an object whose destructor runs the lambda at scope exit.
- If control leaves the guarded block without an existing exception, an exception raised in finally or a destructor is propagated normally.
- If an exception is already propagating and finally/destructor throws, Java, Python, JavaScript and C# overwrite the original exception with the new one.
- Python 3.2 introduced preserving the original exception as the context of the new exception, though the new exception is still the one raised.
- In C++, if a destructor throws while another exception is already propagating (during stack unwinding), the program is terminated.
- wil::scope_exit documents that it will terminate the process if the lambda throws; wil::scope_exit_log is an alternative that logs and ignores exceptions thrown from the lambda.
- The Microsoft compiler supports __try and __finally for structured exception handling in C, but those constructs are not recommended for use in C++.
What to watch next
- Make sure cleanup code run from destructors does not allow exceptions to escape, especially during stack unwinding.
- When using wil::scope_exit, note that a thrown exception from the lambda will terminate the process; consider wil::scope_exit_log if you want to log-and-ignore.
- not confirmed in the source
Quick glossary
- RAII: Resource Acquisition Is Initialization — a C++ idiom where resource lifetime is tied to object lifetime; destructors release resources when objects go out of scope.
- Destructor: A special member function in C++ that runs when an object is destroyed, typically used to free resources or run cleanup code.
- finally clause: A language construct in some languages that guarantees execution of a block of code when control leaves a try block, regardless of whether an exception occurred.
- Stack unwinding: The process of unwinding the call stack during exception propagation, calling destructors for automatic objects as execution moves up the stack.
Reader FAQ
Does C++ have a finally keyword?
No — C++ does not provide a finally clause; developers use destructors and RAII to run cleanup at scope exit.
What happens if a destructor throws while another exception is propagating?
In C++, that situation causes automatic program termination (process abort).
Can I use __try/__finally in MSVC to get finally behavior in C++?
The Microsoft compiler supports __try/__finally for structured exception handling in C, but the blog advises not to use those constructs in C++ because they interact with C++ exceptions in confusing ways.
Does wil::scope_exit mimic Java-style finally behavior?
No — wil::scope_exit will terminate the process if the cleanup lambda throws; wil::scope_exit_log exists to log and ignore such exceptions, and there is no variant that gives Java-like exception-overwrite semantics.

Many languages¹ that have exceptions also have a finally clause, so you can write try { ⟦ stuff ⟧ } finally { always(); } A quick checks shows that this…
Sources
Related posts
- Global Trade Is Shifting: The Dollar’s Era of Dominance May Be Ending
- C++ provides try-finally behavior via destructors, not a finally clause
- Riemann’s Manifold: The Idea That Reframed Mathematics’ View of Space