Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2003-11-01 16:41:12


Brian McNamara <lorgon_at_[hidden]> writes:

> On Thu, Oct 30, 2003 at 02:19:21PM -0800, E. Gladyshev wrote:
>> --- Brian McNamara <lorgon_at_[hidden]> wrote:
>> [...]
>> >
>> > ...the basic guarantee says that, when an exception occurs during a call
>> > to f(), things are still "safe". For example, objects are still in
>> > "safe" states
>>
>> I don't think that it is a true statement. In general
>> you cannot make this assumption.
>> Basic guarantees allow you to break invariants,
>> so the objects may not be in a "safe" state
>> at the *moment* of exception.
>
> Not according to the definition of "basic guarantee" I'm using. See
>
> http://www.boost.org/more/generic_exception_safety.html
>
> which says, among other things
>
> The basic guarantee: that the invariants of the component are
> preserved, and no resources are leaked.
>
> In order to provide the basic guarantee, you have to do work.

Not neccessarily.

> If the class invariant is broken in the middle of a method, and an
> exception is thrown, you must ensure that the class invariant is
> restored by the time the method exits.

Yes.

>> Even if we assume that the abstract objects are "safe",
>> we all know that in practice there is not such thing
>> as abstract C++ machine. If we add the h/w factor into
>> the picture, the question is is it still safe to try
>> to use/destroy objects and possible screw everything up
>> even more? I know that there is probably
>> no a definite answer to this one... just brought it up
>> for the heck of it. :)
>
> Using one of your earlier examples,
>
> class Foo {
> int x, y; // invariant: x+y=10
> public:
> ...
> void m() {
> x = 0; // break inv.
> foo(); // may raise h/w exception
> y = 10;
> }
> };
>
> This class does not provide the basic guarantee.

I beg to differ. Hardware exceptions are not (neccessarily) C++
exceptions, so as far as I'm concerned, foo might as well crash ;-) If
you take out the "h/w" above I'll agree.

> In order to provide
> it, it must do something like
>
> void m() {
> x = 0; // break inv.
> try {
> foo(); // may raise h/w exception
> y = 10;
> }
> catch(...) {
> y = 10;
> throw;
> }
> }
>
> or
>
> void m() {
> x = 0; // break inv.
> ScopeGuard g( var(y)=10 ); // when g is destroyed,
> // boost::lambda function is called to restore invariant
> foo(); // may raise h/w exception
> } // restore invariant via g's destructor
>
> Agree/disagree/other comments?

Righto.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk