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?
In C++ the finally is NOT required because of RAII.
RAII moves the responsibility of exception safety from the user of the object to the designer (and implementer) of the object. I would argue this is the correct place as you then only need to get exception safety correct once (in the design/implementation). By using finally you need to get exception safety correct every time you use an object.
Also IMO the code looks neater (see below).
Example:
A database object. To make sure the DB connection is used it must be opened and closed. By using RAII this can be done in the constructor/destructor.
C++ Like RAII
The use of RAII makes using a DB object correctly very easy. The DB object will correctly close itself by the use of a destructor no matter how we try and abuse it.
Java Like Finally
When using finally the correct use of the object is delegated to the user of the object. i.e. It is the responsibility of the object user to correctly to explicitly close the DB connection. Now you could argue that this can be done in the finaliser, but resources may have limited availability or other constraints and thus you generally do want to control the release of the object and not rely on the non deterministic behavior of the garbage collector.
Also this is a simple example.
When you have multiple resources that need to be released the code can get complicated.
A more detailed analysis can be found here: http://accu.org/index.php/journals/236
Beyond making clean up easy with stack-based objects, RAII is also useful because the same 'automatic' clean up occurs when the object is a member of another class. When the owning class is destructed, the resource managed by the RAII class gets cleaned up because the dtor for that class gets called as a result.
This means that when you reach RAII nirvana and all members in a class use RAII (like smart pointers), you can get away with a very simple (maybe even default) dtor for the owner class since it doesn't need to manually manage its member resource lifetimes.
Another "finally" block emulation using C++11 lambda functions
Let's hope the compiler will optimize the code above.
Now we can write code like this:
If you wish you can wrap this idiom into "try - finally" macros:
Now "finally" block is available in C++11:
Personally I don't like the "macro" version of "finally" idiom and would prefer to use pure "with_finally" function even though a syntax is more bulky in that case.
You can test the code above here: http://coliru.stacked-crooked.com/a/1d88f64cb27b3813
PS
If you need a finally block in your code, then scoped guards or ON_FINALLY/ON_EXCEPTION macros will probably better fit your needs.
Here is short example of usage ON_FINALLY/ON_EXCEPTION:
I have a use case where I think
finally
should be a perfectly acceptable part of the C++11 language, as I think it is easier to read from a flow point of view. My use case is a consumer/producer chain of threads, where a sentinelnullptr
is sent at the end of the run to shut down all threads.If C++ supported it, you would want your code to look like this:
I think this is more logical that putting your finally declaration at the start of the loop, since it occurs after the loop has exited... but that is wishful thinking because we can't do it in C++. Note that the queue
downstream
is connected to another thread, so you can't put in the sentinelpush(nullptr)
in the destructor ofdownstream
because it can't be destroyed at this point... it needs to stay alive until the other thread receives thenullptr
.So here is how to use a RAII class with lambda to do the same:
and here is how you use it:
I also think that RIIA is not a fully useful replacement for exception handling and having a finally. BTW, I also think RIIA is a bad name all around. I call these types of classes 'janitors' and use them a LOT. 95% of the time they are neither initializing nor acquiring resources, they are applying some change on a scoped basis, or taking something already set up and making sure it's destroyed. This being the official pattern name obsessed internet I get abused for even suggesting my name might be better.
I just don't think it's reasonable to require that that every complicated setup of some ad hoc list of things has to have a class written to contain it in order to avoid complications when cleaning it all back up in the face of needing to catch multiple exception types if something goes wrong in the process. This would lead to lots of ad hoc classes that just wouldn't be necessary otherwise.
Yes it's fine for classes that are designed to manage a particular resource, or generic ones that are designed to handle a set of similar resources. But, even if all of the things involved have such wrappers, the coordination of cleanup may not just be a simple in reverse order invocation of destructors.
I think it makes perfect sense for C++ to have a finally. I mean, jeez, so many bits and bobs have been glued onto it over the last decades that it seems odd folks would suddenly become conservative over something like finally which could be quite useful and probably nothing near as complicated as some other things that have been added (though that's just a guess on my part.)
Actually, languages based on Garbage collectors need "finally" more. A garbage collector does not destroy your objects in a timely manner, so it can not be relied upon to clean up non-memory related issues correctly.
In terms of dynamically-allocated data, many would argue that you should be using smart-pointers.
However...
Sadly this is its own downfall. Old C programming habits die hard. When you're using a library written in C or a very C style, RAII won't have been used. Short of re-writing the entire API front-end, that's just what you have to work with. Then the lack of "finally" really bites.