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