Since I'm pretty new to C++, I wasn't too deeply familiar with RAII; like most Schemers I just thought of it as "C++'s version of dynamic-wind."
This week I learned an important distinction between C++ destructors and Java's finally. The latter, of course, unilaterally executes when the body terminates, regardless of how or when it terminates. The thing that gives destructors more expressiveness for dealing with cleanup is that they only execute for the objects that have been initialized. This means that if control exits a block after only half of the stack-local objects have been constructed, only those half of the objects have their destructors invoked. With finally, all that bookkeeping is the responsibility of the programmer.
(That said, I still see RAII used all over the place to construct awkward, special-purpose classes whose sole purpose is to run some cleanup code. In these cases, having to create a named object and a named class to go along with it is pretty perverse.)
Saturday, June 12, 2010
Subscribe to:
Post Comments (Atom)


7 comments:
The other major benefit of RAII over a "finally" block is that the former cannot be forgotten: programmers can easily write poor code by forgetting a finally block, but they cannot make the same mistake if the functions they call return only resources managed by classes with appropriate destructors.
Lately, I've thought of Dorothy's departure from Oz as a non-local exit, like an exception throw or continuation invocation, combined with resource/object cleanup.
This particular metaphor is aided by the fact that Kansas begins with a `k'. And you can think of the words "I'm melting!" as the sound of destructors in action.
I like Scheme's call-with-input-file (and friends) and Python's "with" statement as approaches to this problem. Both are used to bound regions in which a resource is available for use, with automatic cleanup as appropriate for the type of control transfer used to exit the block. I guess they share some of the problems of RAII, actually, with respect to the need for out-of-line pieces of code for resource management. Does "nested finally" help avoid the manual bookkeeping you mention? Have you been considering any alternatives that combine the virtues of both RAII and finally?
(That said, I still see RAII used all over the place to construct awkward, special-purpose classes whose sole purpose is to run some cleanup code. In these cases, having to create a named object and a named class to go along with it is pretty perverse.)
You can get rid of some of this boilerplate with smart pointer classes that take a function to call when the pointer goes out of scope. Something like boost::shared_ptr allows you to pass a function in to be called when it goes out of scope.
steck - that is inspired! Hope you don't mind but i'm having that little visual image to help my memory along as well!
We recently had a very interesting discussion on this subject on cap-talk that you might enjoy: http://www.eros-os.org/pipermail/cap-talk/2011-March/thread.html#14632
Very interesting but over my head, Hardware Man.
Post a Comment