Re: Is this exception-safe code template correct?
On 10/01/10 01:25, DeMarcus wrote:
Hi!
David Abrahams introduced the exception safety guarantees.
http://www.boost.org/community/exception_safety.html
In order to easier create exception safe code I have written a function
code template (a mind template, *not* a C++ template) that I can give to
colleagues, friends, you (if you want), and myself. In the code I have
used Petru Marginean's and Andrei Alexandrescu's ScopeGuard.
http://www.ddj.com/cpp/184403758
The function code template looks like this.
SomeType function( SomeType argument )
{
// Beginning of irreversible, throwing code.
// Non-leaking code here gives Basic Guarantee [D.Abrahams].
// Beginning of reversible, throwing code.
// Code starting here gives Strong Guarantee.
exampleVector_.push_back( "Something" );
ScopeGuard guard1 = makeScopeGuard( exampleVector_,
&std::vector<std::string>::pop_back );
exampleList_.push_back( "Something else" );
ScopeGuard guard2 = makeScopeGuard( exampleList_,
&std::list<std::string>::pop_back );
// ... more code. Only the last operation does not need
// a ScopeGuard.
guard1.dismiss();
guard2.dismiss();
// Beginning of irreversible, non-throwing (non-failing) code.
// Code only here gives No-throw Guarantee.
return;
}
I would gladly hear your comments about it so I can improve it to be
perfect. Please give your thoughts, first and foremost, about how to
write good comments that will guide the programmer to fill in correct
code at correct places. Also if you have ideas how tools like ScopeGuard
can be used, that is welcome too.
In the above code it may be easier to put rollback code in an exception
handler:
SomeType function( SomeType argument )
{
enum { STAGE_0, STAGE_1, STAGE_2 } stage = STAGE_0;
try { // do code
exampleVector_.push_back( "Something" );
stage = STAGE_1;
exampleList_.push_back( "Something else" );
stage = STAGE_2;
// ...
} catch(...) { // reverse order undo code
switch(stage) {
case STAGE_2: exampleList_.pop_back();
case STAGE_1: exampleVector_.pop_back();
default: break;
}
throw;
}
}
This approach is a bit lower level, but, I think, it provides much
greater flexibility than a scope guard.
If scope guards are good enough for you, you might be interested in
Boost.ScopeExit
http://www.boost.org/doc/libs/1_41_0/libs/scope_exit/doc/html/scope_exit/tutorial.html
--
Max
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]