Does C++ support 'finally' blocks?
What is the RAII idiom?
What is the difference between C++'s RAII idiom and C#'s 'using' statement?
Does C++ support 'finally' blocks?
What is the RAII idiom?
What is the difference between C++'s RAII idiom and C#'s 'using' statement?
Sorry for digging up such an old thread, but there is a major error in the following reasoning:
More often than not, you have to deal with dynamically allocated objects, dynamic numbers of objects etc. Within the try-block, some code might create many objects (how many is determined at runtime) and store pointers to them in a list. Now, this is not an exotic scenario, but very common. In this case, you'd want to write stuff like
Of course the list itself will be destroyed when going out of scope, but that wouldn't clean up the temporary objects you have created.
Instead, you have to go the ugly route:
Also: why is it that even managed lanuages provide a finally-block despite resources being deallocated automatically by the garbage collector anyway?
Hint: there's more you can do with "finally" than just memory deallocation.
FWIW, Microsoft Visual C++ does support try,finally and it has historically been used in MFC apps as a method of catching serious exceptions that would otherwise result in a crash. For example;
I've used this in the past to do things like save backups of open files prior to exit. Certain JIT debugging settings will break this mechanism though.
I would like to provide an alternative.
If you want finally block to be called always, just put it after last catch block (which probably should be
catch( ... )
to catch not known exception)If you want finally block as a last thing to do when any exception is thrown you can use boolean local variable - before run you set it to false and put true assignment at the very end of try block, then after catch block check for the variable value:
As pointed out in the other answers, C++ can support
finally
-like functionality. The implementation of this functionality that is probably closest to being part of the standard language is the one accompanying the C++ Core Guidelines, a set of best practices for using C++ edited by Bjarne Stoustrup and Herb Sutter. An implementation offinally
is part of the Guidelines Support Library (GSL). Throughout the Guidelines, use offinally
is recommended when dealing with old-style interfaces, and it also has a guideline of its own, titled Use a final_action object to express cleanup if no suitable resource handle is available.So, not only does C++ support
finally
, it is actually recommended to use it in a lot of common use-cases.An example use of the GSL implementation would look like:
The GSL implementation and usage is very similar to the one in Paolo.Bolzoni's answer. One difference is that the object created by
gsl::finally()
lacks thedisable()
call. If you need that functionality (say, to return the resource once it's assembled and no exceptions are bound to happen), you might prefer Paolo's implementation. Otherwise, using GSL is as close to using standardized features as you will get.In C++11, if needed, RAII allows to make a finally:
example of use:
the output will be:
Personally I used this few times to ensure to close POSIX file descriptor in a C++ program.
Having a real class that manage resources and so avoids any kind of leaks is usually better, but this finally is useful in the cases where making a class sounds like an overkill.
Besides, I like it better than other languages finally because if used naturally you write the closing code nearby the opening code (in my example the new and delete) and destruction follows construction in LIFO order as usual in C++. The only downside is that you get an auto variable you don't really use and the lambda syntax make it a little noisy (in my example in the fourth line only the word finally and the {}-block on the right are meaningful, the rest is essentially noise).
Another example:
The disable member is useful if the finally has to be called only in case of failure. For example, you have to copy an object in three different containers, you can setup the finally to undo each copy and disable after all copies are successful. Doing so, if the destruction cannot throw, you ensure the strong guarantee.
disable example: