Boost logo

Boost :

Subject: Re: [boost] [interest] rich-typed smart pointers
From: Julian Gonggrijp (j.gonggrijp_at_[hidden])
Date: 2013-10-05 15:34:08


namespace rtp = rich_typed_ptr;

Jeremy Maitin-Shepard wrote:

>> I believe multiple ownership in std::shared_ptr is not a goal in
>> itself, but just a way to ensure that objects stay live as long as
>> they're needed. In my opinion I do actually address the problem of
>> multiple ownership by taking it away.
>
> Well, regardless of how you want to look at it, shared_ptr allows an
> arbitrary acyclic ownership/"ensure pointers stay alive" graph, while
> unique_ptr only allows an ownership forest.
>
>> [...]

>>> I think the primary use case for your proposed weak_ptr (possibly renamed
>>> param_ptr or arg_ptr) would be as the declared type for function parameters.
>>
>> That, and as a way to create arbitrarily complex linked data
>> structures without introducing ownership problems. Note how this
>> makes it more similar to std::weak_ptr than you may have thought
>> initially.
>
> I think that's overselling it a bit. It only supports tree structures (with
> possible back pointers using raw pointers/your proposed weak_ptr).
> Certainly in many cases a tree structure is all that is needed, but
> sometimes a more general ownership graph is needed.

Let us be very precise. Ownership graphs using rtp::data_ptr allow
rings and trees. Rings cannot overlap, but each ring node may at
the same time be the root node of a tree. To be honest I find myself
unable to imagine a data structure that needs even more complex
ownership than that. Graph containers with a linked implementation
for example only need tree-like ownership, with reference cycles
closed by non-owning pointers.

Regardless, this is just the *automatic* ownership part of the
general pointer graph; using rtp::weak_ptr (to be renamed) one can
create any arbitrary graph, and the user can implement ownership
on top of that because it is possible to break a rtp::data_ptr chain
using access through a rtp::weak_ptr. I like to call this
meta-ownership and I have demonstrated its use for a cyclically
owned data structure in my linked ring example.

>>
>> Could you elaborate on why implicit conversion to my weak_ptr would be
>> dangerous?
>
> Because the weak_ptr may outlive the underlying object, and the implicit
> conversion makes it silent. The only context in which this can't happen is
> if the weak_ptr is used only as a function parameter type. A dangling
> reference is quite possible if used as a return type or struct/class member,
> or even a local variable. It is best to limit implicit conversions to cases
> that are guaranteed to be safe, and can't possibly result in a dangling
> reference. If it is possibly unsafe, there should be some syntactic cue
> indicating as much.
>
>
>> Since type deduction is only rudimental in C++11, there actually is
>> such a warning signal:
>>
>> auto x = weak(foo);
>
> Sure, in this case there is a syntactic cue, although it is perhaps not
> strong enough: "weak reference" typically means a non-owning reference that
> nonetheless knows when the reference becomes invalid, and therefore is still
> safe. This is the case for std::weak_ptr, as well as weak references in
> most other languages. For that reason I think it would be better to choose
> a different name.

I agree that the name is too suggestive of semantics similar to
std::weak_ptr. I'll change it.

As for safety, I think std::weak_ptr is not really safer that rtp::weak_ptr
because it's just as easy to produce a dangling pointer (in fact std takes
only 3 lines of code to do it while rtp requires 4) and that's a disaster no
matter what. The fact that it can detect that it's dangling does however
make it easier to debug.

Again, thanks for your feedback.

-Julian


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