[MS] All the other cool languages have try...finally. C++ says "We have try...finally at home." - devamazonaws.blogspot.com

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

try {
    ⟦ stuff ⟧
} finally {
    always();
}

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

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 ⟧

Although the principle is the same, there are some quirks in how each language treats the case where the finally or destructor itself throws an exception.

If control leaves the 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.

If control leaves the block with an exception, and the finally block or destructor also throws an exception, then the behavior varies by language.

  • In Java, Python, JavaScript, and C# an exception thrown from a finally block overwrites the original exception, and the original exception is lost.
  • In C++, an exception thrown from a destructor triggers automatic program termination if the destructor is running due to an 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.

¹ The Microsoft compiler also supports the __try and __finally keywords for structured exception handling. These are, however, intended for C code. Don't use them in C++ code because they interact with C++ exceptions in sometimes-confusing ways.

² 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 that are thrown from the lambda. There is no variation that gives you Java-like behavior.


Post Updated on December 22, 2025 at 03:00PM
Thanks for reading
from devamazonaws.blogspot.com

Comments

Popular posts from this blog

[MS] Pulling a single item from a C++ parameter pack by its index, remarks - devamazonaws.blogspot.com

[MS] Debugger breakpoints are usually implemented by patching the in-memory copy of the code - devamazonaws.blogspot.com

[MS] The case of the crash when destructing a std::map - devamazonaws.blogspot.com