On Mon, Jun 11, 2012 at 11:51 PM, Pekka Seppänen <pekka.seppanen@capricode.com> wrote:
On 11.6.2012 19:47, Travis Gockel wrote:
> The copy constructor for weak_ptr constructs px like so:
>
> px(r.lock().get())
>
> Why do it this way and not just:
>
> px(r.px)
>
> This introduces a somewhat unexpected race in that the shared_ptr obtained
> with lock() can be the last outstanding shared_ptr and the object can be
> destroyed during this copy. It is certainly not a /bug/ in the smart_ptr
> library, but the behavior is unexpected and quite inconvenient. I assume there
> is a reason for calling lock() and not just copying the pointer and I would
> like to know what it is.
>

This is actually commented in smart_ptr/weak_ptr.hpp (just above the first
px(r.lock().get()) construction thing):

//
//  The "obvious" converting constructor implementation:
//
//  template<class Y>
//  weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
//  {
//  }
//
//  has a serious problem.
//
//  r.px may already have been invalidated. The px(r.px)
//  conversion may require access to *r.px (virtual inheritance).
//
//  It is not possible to avoid spurious access violations since
//  in multithreaded programs r.px may be invalidated at any point.
//


-- Pekka
_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

I suppose that makes sense and I should learn to read. Does that mean the default implementation will work just fine in cases where there is no conversion needed?

    weak_ptr(weak_ptr const& r) = default;

--
Travis Gockel
Chief λ Combinator