[PATCH] D28245: ADT: IntrusiveRefCntPtr: Broaden the definition of correct usage of RefCountedBase

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 3 11:47:12 PST 2017


On Tue, Jan 3, 2017 at 11:43 AM Justin Lebar via Phabricator <
reviews at reviews.llvm.org> wrote:

> jlebar requested changes to this revision.
> jlebar added a comment.
> This revision now requires changes to proceed.
>
> I think what I wrote on the mailing list applies here:
>
> > btw I don't think it's at all so simple.  For example, an object
> >  might, in one of its member functions, cause itself to be
> >  retained/released.  This is perfectly valid, but of course will break
> >  you in exciting ways if you allocate the object on the stack.
> >
> > The advice of "it's safe to allocate these objects on the stack if
> >  you're careful and the object doesn't ever cause itself to be
> >  retained/released" really means "if the object doesn't *currently*
> >  ever cause itself to be retained/released".  IOW allocating such an
> >  object on the stack constrains future changes to the object's
> >  implementation.  If I had to do a cleanup of code I didn't care about
> >  that was allocating such an object on the stack before I could land a
> >  change I cared about, I'd be pretty annoyed, and rightfully so, I
> >  think.
> >
> > That is to say, unless it's part of an object's contract that it never
> >  causes itself to be retained/released, I think you're in for a bad
> >  time.  Indeed, the same applies for every function you pass that
> >  object to: Unless it is part of that function's contract that it never
> >  causes the object to be retained or released, passing a
> >  stack-allocated object to such a function is going to constrain future
> >  changes to the implementation of that function and all transitive
> >  callees.
> >
> > This seems like an extremely unfriendly thing to do.
>
> That is, as written this comment seems to say that it's OK for me to take a
> class that inherits from RefCountedBase and allocate it on the stack if I
> am
> careful about it.  But doing so constrains the author of the class from
> ever
> calling Retain/Release on itself.  I think our default should be that this
> is
> allowed, which implies that our default should be that allocating such
> objects
> on the stack is disallowed.
>

I feel like the default should be the opposite (which is
std::enable_shared_from_this's position as well) - that the need for
intrusive reference counting would /allow/ the type to be owned in this
way, but not require it. If a type requires it, it could document that (on
any specific operations, or universally).


> If a class explicitly promises never to Retain/Release itself, then
> allocating
> it on the stack is fine.  However, for the same reason, you should only
> pass it
> to functions that promise never to Retain/Release the object.
>
> I'm fine if you want to write this up in a comment, although I am curious
> what
> problem you're trying to solve.
>

Broadly: That ownership semantics are kept orthogonal to types as much as
possible. That some users of a type may need to leverage intrusive
reference counting (to get through some interface that can't accurately
model the ownership in the interim, for example) shouldn't so-constrain all
users to use the type that way.

- Dave


>
>
> https://reviews.llvm.org/D28245
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170103/26694a28/attachment.html>


More information about the llvm-commits mailing list