Exception handling in C++ is limited to try/throw/catch. Unlike Object Pascal, Java, C# and Python, even in C++ 11, the finally
construct has not been implemented.
I have seen an awful lot of C++ literature discussing "exception safe code". Lippman writes that exception safe code is an important but advanced, difficult topic, beyond the scope of his Primer – which seems to imply that safe code is not fundamental to C++. Herb Sutter devotes 10 chapters to the topic in his Exceptional C++ !
Yet it seems to me that many of the problems encountered when attempting to write "exception safe code" could be quite well solved if the finally
construct was implemented, allowing the programmer to ensure that even in the event of an exception, the program can be restored to a safe, stable, leak-free state, close to the point of allocation of resources and potentially problematic code. As a very experienced Delphi and C# programmer I use try.. finally blocks quite extensively in my code, as do most programmers in these languages.
Considering all the 'bells and whistles' implemented in C++ 11, I was astonished to find that 'finally' was still not there.
So, why has the finally
construct never been implemented in C++? It's really not a very difficult or advanced concept to grasp and goes a long ways towards helping the programmer to write 'exception safe code'.
Best Answer
It's really just a matter of understanding the philosophy and idioms of C++. Take your example of an operation that opens a database connection on a persistent class and has to make sure that it closes that connection if an exception is thrown. This is a matter of exception safety and applies to any language with exceptions (C++, C#, Delphi...).
In a language that uses
try
/finally
, the code might look something like this:Simple and straightforward. There are, however, a few disadvantages:
finally
block, otherwise I leak resources.DoRiskyOperation
is more than a single method call - if I have some processing to do in thetry
block - then theClose
operation can end up being a decent bit away from theOpen
operation. I can't write my cleanup right next to my acquisition.try
/finally
blocks.The C++ approach would look like this:
This completely solves all of the disadvantages of the
finally
approach. It has a couple of disadvantages of its own, but they're relatively minor:ScopedDatabaseConnection
class yourself. However, it's a very simple implementation - only 4 or 5 lines of code.Personally, considering these advantages and disadvantages, I find RAII (Resource Acquisition Is Initialization) a much preferable technique to
finally
. Your mileage may vary.Finally, because RAII is such a well-established idiom in C++, and to relieve developers of some of the burden of writing numerous
Scoped...
classes, there are libraries like ScopeGuard and Boost.ScopeExit that facilitate this sort of deterministic cleanup.