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