|
Boost : |
Subject: Re: [boost] [interest] rich-typed smart pointers
From: Julian Gonggrijp (j.gonggrijp_at_[hidden])
Date: 2013-10-07 09:41:03
Larry Evans wrote:
> On 10/07/13 05:45, Jonathan Wakely wrote:
>> On 7 October 2013 11:01, Julian Gonggrijp wrote:
>>>
>>> The std::weak_ptr detects the dangling pointer and changes it into a
>>> null pointer. This makes sense, because null pointers are easier to
>>> detect. However, as the surrounding code probably relies on a live
>>> pointer (because dangling pointers are never planned) the program is
>>> still going to fail. This is what I meant by "disaster".
>>
>> Why is it going to fail? Expired pointers (not dangling ones) most
>> certainly are planned, and weak_ptr is designed to support (and
>> detect) that case. Users of std::weak_ptr know that it needs to be
>> checked, and the explicit conversion that is needed makes it hard to
>> forget to do that. Either you say:
>>
>> std::shared_ptr<X> sp(wp);
>>
>> which will throw if weak_ptr.expired() is true, or you use the
>> non-throwing form in a conditional:
>>
>> if (auto sp = wp.lock())
>> /* ... */ ;
>> else
>> /* deal with it */ ;
>>
> To provide a concrete example, the attached code produces:
>
> ***test_run<1>::run()
> { obj_id+:10, obj_count:1}
> { obj_id+:11, obj_count:2}
> inner empty(wp)=0
> inner deref(wp).my_id=11
> { obj_id-:11, obj_count:1}
> exited inner
> outer empty(wp)=0
> outer deref(wp).my_id=0
> { obj_id-:10, obj_count:0}
> exited outer
> ***test_run<0>::run()
> { obj_id+:12, obj_count:1}
> { obj_id+:13, obj_count:2}
> inner empty(wp)=0
> inner deref(wp).my_id=13
> { obj_id-:13, obj_count:1}
> exited inner
> outer empty(wp)=1
> make: *** [run] Segmentation fault (core dumped)
>
> where the output prefixed with ***test_run<0>::run used
> the std:: smart pointers and shows the detection of
> expired weak_ptr:
>
> outer empty(wp)=1
>
> and caused a segfault when it deref'ed the wp.
>
> In contrast, the output prefixed with ***test_run<1>::run,
> which uses the rich_type_ptr smart pointers,
> does *not* detect the expired weak pointer; consequently,
> does not cause a segfault when dereferencing that pointer,
> which, in a real program, would make it harder to find
> the bug.
As far as I'm concerned this outcome is expected. I thought we already
agreed about the existence of this difference in behaviour between
std::weak_ptr and rtp::weak_ptr? I even already announced that I would
change the name of rtp::weak_ptr to something else for exactly this
reason, several emails ago.
-Julian
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk