On Wed, Aug 13, 2014 at 9:42 AM, Jeff Walden <jwalden+...@mit.edu> wrote:
> So at risk of adding yet another flavor of thing: why not introduce an 
> already_AddRefed<T> sort of struct that *does* own an addref, *will* release 
> on destruction if not nulled out, and does *not* explicitly convert to T*?  
> Give nsCOMPtr move constructors and move assignment operators from that 
> class, that null out this other pointer when called, to transfer ownership at 
> no cost.  (At risk of overplaying my hand, I think I've just described what 
> WebBlink calls PassRefPtr, except for that pertaining to concrete classes 
> whereas nsCOMPtr<T> is for abstract T classes.)
>
> I recognize this introduces yet another way to do things.  But it enables 
> incremental transition to a completely safe system that prohibits assignment 
> of a method call to a raw pointer, and yet never has problems with leaks.  If 
> we work hard at enforcing this on the way in, it can quickly become second 
> nature, I think.

I think this can be improved upon a bit further: just change
already_AddRefed to behave more similarly to nsCOMPtr, but still not
convert to T* implicitly.  So for instance:

* Change ~already_AddRefed to just release the pointer instead of
asserting.  This means it would be perfectly okay to ignore the result
of a function that returns already_AddRefed.

* Make an already_AddRefed constructor from T* (which would addref).
This allows you to return a raw pointer from a function with
already_AddRefed return type, and it will do the right thing without
you having to define an nsCOMPtr temporary.

* Make an already_AddRefed constructor from nsCOMPtr/nsRefPtr (which
would addref if the source is an lvalue, and steal the value if the
source is an rvalue).  This allows you to return a local nsCOMPtr or
nsRefPtr directly, without having to call .forget().  If we want to be
extra careful to avoid accidental addrefs, we could allow construction
only from rvalues, but I'm not sure this is a good idea.

* Allow conversion of already_AddRefed to bool, and comparison to T*.

This has most of the benefits of my original proposal, without the
drawback David and Ehsan object to.  It has the advantage of not
having to change the return type of a few thousand functions.  It has
the disadvantage that you could still not pass an already_AddRefed
directly to a function that wants T*, which is unfortunate because
it's perfectly safe to do so.  I can't think of any way to avoid that
except defining new types for refcounted parameters to use instead of
raw pointers (which would have other uses as well).

David, Ehsan, what do you think?
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to