Skip to main content

Why is there no 'finally' construct in C++? [Resolved]

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'.


Question Credit: Vector
Question Reference
Asked December 14, 2017
Tags: , exceptions
Posted Under: Programming
44 views
7 Answers

From Why doesn't C++ provide a "finally" construct? in Bjarne Stroustrup's C++ Style and Technique FAQ:

Because C++ supports an alternative that is almost always better: The "resource acquisition is initialization" technique (TC++PL3 section 14.4). The basic idea is to represent a resource by a local object, so that the local object's destructor will release the resource. That way, the programmer cannot forget to release the resource.


credit: svick
Answered December 14, 2017

As some additional commentary on @Nemanja's answer (which, since it quotes Stroustrup, is really about as good of an answer as you can get):

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:

database.Open();
try {
    database.DoRiskyOperation();
} finally {
    database.Close();
}

Simple and straightforward. There are, however, a few disadvantages:

  • If the language doesn't have deterministic destructors, I always have to write the finally block, otherwise I leak resources.
  • If DoRiskyOperation is more than a single method call - if I have some processing to do in the try block - then the Close operation can end up being a decent bit away from the Open operation. I can't write my cleanup right next to my acquisition.
  • If I have several resources that need to be acquired then freed in an exception-safe manner, I can end up with several layers deep of try / finally blocks.

The C++ approach would look like this:

ScopedDatabaseConnection scoped_connection(database);
database.DoRiskyOperation();

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:

  • There's a good chance you need to write the ScopedDatabaseConnection class yourself. However, it's a very simple implementation - only 4 or 5 lines of code.
  • It involves creating an extra local variable - which you're apparently not a fan of, based on your comment about "constantly creating and destroying classes to rely on their destructors to clean up your mess is very poor" - but a good compiler will optimize out any of the extra work that an extra local variable involves. Good C++ design relies a lot on these sorts of optimizations.

Personally, considering these advantages and disadvantages, I find RAII 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.


credit: Community
Answered December 14, 2017

Others have discussed RAII as the solution. It's a perfectly good solution. But that doesn't really address why they didn't add finally as well since it's a widely desired thing. The answer to that is more fundamental to the design and development of C++: throughout the development of C++ those involved have strongly resisted the introduction of design features that can be achieved using other features without a huge amount of fuss and especially where this requires the introduction of new keywords that could render older code incompatible. Since RAII provides a highly functional alternative to finally and you can actually roll your own finally in C++11 anyway, there was little call for it.

All you need to do is create a class Finally that calls the function passed to it's constructor in it's destructor. Then you can do this:

try
{
    Finally atEnd([] () { database.close(); });

    database.doRisky();
}

Most native C++ programmers will, in general, prefer cleanly designed RAII objects however.


credit: Jack Aidley
Answered December 14, 2017

You can use a "trap" pattern - even if you don't want to use try/catch block.

Put a simple object in the required scope. In this object's destructor put your "finaly" logic. No matter what, when the stack is unwound, object's destructor will be called and you'll get your candy.


credit: Arie R
Answered December 14, 2017
Your Answer
D:\Adnan\Candoerz\CandoProject\vQA