Boost logo

Boost :

Subject: Re: [boost] [smart_ptr] Interest in the missing smart pointer (that can target the stack)
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2016-01-29 05:25:49


On 2016-01-29 12:40, Rob Stewart wrote:
> On January 29, 2016 2:48:56 AM EST, Emil Dotchevski <emildotchevski_at_[hidden]> wrote:
>> On Thu, Jan 28, 2016 at 7:57 PM, Michael Marcin
>> <mike.marcin_at_[hidden]>
>> wrote:
>>
>>> On 1/28/2016 8:09 PM, Emil Dotchevski wrote:
>>>
>>>> And it's way too easy to break that guarantee because it's not the
>>>>> semantics that shared_ptr was designed for.
>>>>>
>>>>>
>>>> {
>>>> foo local;
>>>> shared_ptr<foo> pl(&local,null_deleter());
>>>> ....
>>>> do_something(p);
>>>> ....
>>>> assert(pl.unique());
>>>> }
>>>>
>>>> Yes, in the presence of exceptions one must also
>> assert(pl.unique()) in a
>>>> catch(...), and yes, compile-time errors are better than run-time
>> errors,
>>>> but I wouldn't sacrifice the availability of weak_ptr and the
>> capacity of
>>>> shared_ptr to act as THE single smart pointer framework in a
>> program.
>>>>
>>> Why on earth would you ever do this?
>>
>> One reason is to get weak_ptr.
>>
>>> There is no shared ownership semantics here at all.
>>
>> The point of shared_ptr is to be able to reason that as long as you
>> hold on
>> to a shared_ptr (which you might get by copying another shared_ptr or
>> by
>> locking a weak_ptr), the object will not expire, but you don't hold on
>> to
>> it longer than you need to. This reasoning is perfectly valid within
>> the scope of do_something.
>
> If do_something() saves a copy of the shared pointer in a container, for example, later references will refer to a non-existent object. There's nothing you can do about it short of using assertions or another runtime check with a call to std::terminate() or similar. That's hardly ideal.

I think what Emil describes is a special case of a 'dangling_ptr' idiom,
if I may call it that way. The point is that there are cases when object
lifetime is controlled by a third party (e.g. the stack state, a foreign
library, etc.) and you need a safe way to know when the object has been
deleted. So you create a shared_ptr with a null_deleter pointing to that
object and save it in that object (or another storage associated with
that object). You keep only weak_ptrs to that object in all other places
in the code. When you need to use the object you have to lock a weak_ptr
and thus check if the object is still alive.

The example Emil presented is not quite clear to demonstrate the
approach because do_something should be receiving weak_ptr rather than
shared_ptr.


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