Boost logo

Boost :

Subject: Re: [boost] [interest] rich-typed smart pointers
From: Jeremy Maitin-Shepard (jeremy_at_[hidden])
Date: 2013-10-03 12:43:31


Julian Gonggrijp <j.gonggrijp <at> gmail.com> writes:

>
> Jeremy Maitin-Shepard wrote:
>
> > From reading the documentation, it seems that owner_ptr/data_ptr are
> > basically equivalent in functionality to std::unique_ptr, and weak_ptr is
> > basically equivalent to a raw pointer/raw reference. (Referring to
> > std::shared_ptr seems a bit misleading given that you don't address the
> > problem of multiple ownership.)
>
> Well I think there are two ways to see it. I was motivated by both of
> them:
>
> std::unique_ptr + added safety + non-owning companion smart pointer type
>
> (as you suggested) or
>
> std::shared_ptr + std::weak_ptr - accidental cyclic ownership - runtime
overhead
>
> 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.
 
>
> As for the rich-typed weak_ptr, I think you should really think of it
> as a smart pointer, if only because it doesn't allow the user to
> deallocate the referenced object.
>
> > As I understand it, the goal of your
> > library is not to add any functionality over std::unique_ptr, but to provide
> > a little bit more compile-time safety at the cost of some additional typing
> > (pun intended).
>
> Well, yes. I do consider that additional functionality.
>
> > It does seem that wrappers around unique_ptr and shared_ptr
> > that disable default construction and discourage storing a null pointer
> > would be useful for many people. It would be much more useful if they
> > explicitly interoperated with those types, though.
>
> Fortunately it is trivial to add some interoperability with the std::
> pointers. I'll add that to the roadmap.
>
> >
> > 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.

>
> I do like your suggestion for the name param_ptr or arg_ptr, though.
> I've been considering whether I should split weak_ptr in two types,
> one for function arguments and one for linked data structures. In
> that case your name suggestions would be excellent for the former
> while I could keep using the name weak_ptr for the latter. This would
> allow me to enforce that the proposed param_ptr is always non-null so
> that functions can rely on that.

Perhaps it would be useful to have both a possibly null and a non-null
variant of param_ptr, where the non-null version has a runtime check.

>
> > When used only in that context, the implicit conversion from an owning
> > pointer to a raw pointer is safe, because any values used as function
> > arguments are guaranteed to live for the duration of the function.
> >
> > For any other use, though, the implicit conversion is actually dangerous,
>
> 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.


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