Boost logo

Boost :

From: David B. Held (dheld_at_[hidden])
Date: 2003-02-01 12:56:31

I started a new thread because the old one was getting hard to
follow on my newsreader from the excessive nesting. I realized
there is yet another problem with my scheme (which should come
as no suprise by now). This time, the problem is the copy c'tor.
Here's a recap:

    storage::storage(storage const& rhs)
    : pointee_(rhs.pointee_)
    { }

    { checked_delete(pointee_); }

    void storage::release()
    { pointee_ = default_value(); }

    ref_counted::ref_counted(ref_counted const& rhs)
    : count_(rhs.count_)
    { }

    { delete count_; }

    bool ref_counted::release(P const& p)
        if (!--*count_) return true;
        count_ = 0; return false;

    smart_ptr::smart_ptr(smart_ptr const& rhs)
    : storage(rhs), ownership(rhs), checking(rhs), conversion(rhs)
    { checking::on_init(p); }

        if (!ownership::release(get_impl(*this)))

The problem is that while ref_counted indeed cleans up its count in
the face of later exceptions, it may do so prematurely. For instance,
if checking(rhs) were to throw, ~smart_ptr() does not get a chance
to call ownership::release(), which prevents ownership from deleting
the count. Similarly, if, for some reason, ownership(rhs) were to
throw, storage might prematurely free the resource. The two most
viable solutions I can think of are:

A) add scope guards to make sure the right thing is done no matter
who throws

B) require that copying be no-throw

The problem with A) is that it imposes a performance penalty on
copying, which might be seen as undesirable. The problem with B)
is that deep_copy would probably like to throw. I guess there is
a third option:

C) require no-throw semantics only for certain policy configurations

Which is, of course, what I've already suggested for the P const& p
c'tors. Comments?


Boost list run by bdawes at, gregod at, cpdaniel at, john at