Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2003-12-11 10:38:38


Rani Sharoni wrote:
> Peter Dimov wrote:
>> Have you read
>>
>> http://www.boost.org/libs/smart_ptr/sp_techniques.html
>
> Thanks for this awesome usability demonstration!
> Maybe it will help me to convince some people in my work place to
> start using shared_ptr.
>
> I have few comments regarding failure guaranties. In general I think
> that weakening failure guarantee is something that should be avoided
> and I saw few places in your paper in which adding shared_ptr changed
> the failure guarantee from no-fail into fail with std::bad_alloc since
> share_ptr constructor might throw it.

This may indeed be a potential problem, but in practice...

> For example:
> 1) Using shared_ptr as CopyConstructible mutex lock: lock had no fail
> guarantee.

Acquire-style functions such as lock() typically don't need the nothrow
guarantee; unlock() does. If a nothrow lock() is important, the lock object
would need to be moveable. ;-)

> 2) Using shared_ptr to wrap member function calls: operator-> might
> have no fail guarantee. E.g. pointer<X> p; p->cleanup();

Correct, the quick shared_ptr solution has a problem with nothrow regions
when prefix() is nothrow. A better pointer<> would be moveable, and more
complicated.

> 3) Delayed deallocation: Y::f() called px.reset that had no fail and
> vector::push_back might throw.

This is fortunately not a problem. Had Y::f() been nothrow, the only fix
needed is to wrap push_back in a try-catch(...) {} block, falling back to
immediate deallocation when the free list is "full".

> One question: why shared_count::shared_count(weak_count const &)
> throws boost::bad_weak_ptr and what can be done when catching such
> exceptions?

The corresponding nothrow equivalent is weak_ptr::lock:

if( shared_ptr<X> px = wp.lock() )
{
    // do something with *px
}
else
{
    // handle the wp.expired() case
}

The constructor should be used in situations where, well, an expired
weak_ptr should cause an exception. :-)

For example, let's say that you have a list of function objects that need to
be invoked periodically (once per second, or once per frame.) Some of these
function objects may, directly or indirectly, hold weak pointers to objects
in the "application world". When such a weak pointer expires, the function
object throws bad_weak_ptr from its operator(), and you respond by removing
it from the list.

> It seems to have potential impact on the failure guaranty
> of many functions such as impl::getX (Obtaining a shared_ptr to this).

In this case, bad_weak_ptr signals that the object is not managed by a
shared_ptr, i.e. a programming error.


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