Sounds like we should work to eliminate the implicit conversion to T*.
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
operator void*() sgtm.
Wasn't it better to convert to void* instead of bool? If you have a conversion to bool, you get "conversion" to integer for free...
My plan of attack is to write a Clang plugin and bulk fix everything.
I am only going to bulk fix so we can ditch the implicit conversion operator. I do not believe this will change any function signatures, but may change some invocations to insert the .get(), which hopefully the clang rewriter would take care of. I'm going to consider your example of changing the return type as out of scope. Does that seem reasonable?
So I looked into it. I've uploaded a partial changelist (my clang rewriter crapped out due to some overlapping replacements when we have nested expressions using the implicit operator T*): http://codereview.chromium.org/download/issue11275088_1.diffOne thing I don't like is the stuff like MessageLoopProxy::current().get() or Profile::GetForFactory(foo).get(). Pretty gross if you ask me =/Ignore the if (foo.get()) expressions. I'll fix those with the safe operator bool idiom later.I think to fix this completely, we'd need to either allow |const scoped_refptr<T>&| (I know we disallowed this earlier, but maybe we need to revisit) or introduce pass_scoped_refptr<T> or something.
On Wed, Oct 31, 2012 at 4:32 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
So I looked into it. I've uploaded a partial changelist (my clang rewriter crapped out due to some overlapping replacements when we have nested expressions using the implicit operator T*): http://codereview.chromium.org/download/issue11275088_1.diffOne thing I don't like is the stuff like MessageLoopProxy::current().get() or Profile::GetForFactory(foo).get(). Pretty gross if you ask me =/Ignore the if (foo.get()) expressions. I'll fix those with the safe operator bool idiom later.I think to fix this completely, we'd need to either allow |const scoped_refptr<T>&| (I know we disallowed this earlier, but maybe we need to revisit) or introduce pass_scoped_refptr<T> or something.Why? Is it that we don't want to pay for an extra AddRef/Release?
On Wed, Oct 31, 2012 at 4:54 PM, Antoine Labour <pi...@google.com> wrote:
On Wed, Oct 31, 2012 at 4:32 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
So I looked into it. I've uploaded a partial changelist (my clang rewriter crapped out due to some overlapping replacements when we have nested expressions using the implicit operator T*): http://codereview.chromium.org/download/issue11275088_1.diffOne thing I don't like is the stuff like MessageLoopProxy::current().get() or Profile::GetForFactory(foo).get(). Pretty gross if you ask me =/Ignore the if (foo.get()) expressions. I'll fix those with the safe operator bool idiom later.I think to fix this completely, we'd need to either allow |const scoped_refptr<T>&| (I know we disallowed this earlier, but maybe we need to revisit) or introduce pass_scoped_refptr<T> or something.Why? Is it that we don't want to pay for an extra AddRef/Release?Avoids the .get(). Most function parameters are of the form Foo*. If we could change them to const scoped_refptr<Foo>& instead, that'd avoid the caller needing to invoke .get() to pass a Foo*.
On Wed, Oct 31, 2012 at 5:02 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Oct 31, 2012 at 4:54 PM, Antoine Labour <pi...@google.com> wrote:
On Wed, Oct 31, 2012 at 4:32 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
So I looked into it. I've uploaded a partial changelist (my clang rewriter crapped out due to some overlapping replacements when we have nested expressions using the implicit operator T*): http://codereview.chromium.org/download/issue11275088_1.diffOne thing I don't like is the stuff like MessageLoopProxy::current().get() or Profile::GetForFactory(foo).get(). Pretty gross if you ask me =/Ignore the if (foo.get()) expressions. I'll fix those with the safe operator bool idiom later.I think to fix this completely, we'd need to either allow |const scoped_refptr<T>&| (I know we disallowed this earlier, but maybe we need to revisit) or introduce pass_scoped_refptr<T> or something.Why? Is it that we don't want to pay for an extra AddRef/Release?Avoids the .get(). Most function parameters are of the form Foo*. If we could change them to const scoped_refptr<Foo>& instead, that'd avoid the caller needing to invoke .get() to pass a Foo*.Oops, I misunderstood. You were assuming we'd change the function parameters to be scoped_refptr<T> and do copies. Yes, that'd be an extra AddRef()/Release() pair :(
On Wed, Oct 31, 2012 at 4:32 PM, William Chan (陈智昌)I looked at the first one of the MessageLoopProxy::current().get(),
<will...@chromium.org> wrote:
> So I looked into it. I've uploaded a partial changelist (my clang rewriter
> crapped out due to some overlapping replacements when we have nested
> expressions using the implicit operator T*):
> http://codereview.chromium.org/download/issue11275088_1.diff
>
> One thing I don't like is the stuff like MessageLoopProxy::current().get()
> or Profile::GetForFactory(foo).get(). Pretty gross if you ask me =/
> Ignore the if (foo.get()) expressions. I'll fix those with the safe operator
> bool idiom later.
>
> I think to fix this completely, we'd need to either allow |const
> scoped_refptr<T>&| (I know we disallowed this earlier, but maybe we need to
> revisit) or introduce pass_scoped_refptr<T> or something. I don't think we
> could automate either of these refactors.
> Or we can just give up and stick with a PSA, or live with the ugliness of
> these extra .get() calls.
and it's passing the result to ImportantFileWriter, which takes a
SequencedTaskRunner*. In that case, I think it would be a bad idea to
change the argument to const scoped_refptr<SequencedTaskRunner>&,
since it would enforce a particular ownership structure on all
callers. .get() is the right fix in that case.
On Wed, Oct 31, 2012 at 5:03 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Oct 31, 2012 at 5:02 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Oct 31, 2012 at 4:54 PM, Antoine Labour <pi...@google.com> wrote:
On Wed, Oct 31, 2012 at 4:32 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
So I looked into it. I've uploaded a partial changelist (my clang rewriter crapped out due to some overlapping replacements when we have nested expressions using the implicit operator T*): http://codereview.chromium.org/download/issue11275088_1.diffOne thing I don't like is the stuff like MessageLoopProxy::current().get() or Profile::GetForFactory(foo).get(). Pretty gross if you ask me =/Ignore the if (foo.get()) expressions. I'll fix those with the safe operator bool idiom later.I think to fix this completely, we'd need to either allow |const scoped_refptr<T>&| (I know we disallowed this earlier, but maybe we need to revisit) or introduce pass_scoped_refptr<T> or something.Why? Is it that we don't want to pay for an extra AddRef/Release?Avoids the .get(). Most function parameters are of the form Foo*. If we could change them to const scoped_refptr<Foo>& instead, that'd avoid the caller needing to invoke .get() to pass a Foo*.Oops, I misunderstood. You were assuming we'd change the function parameters to be scoped_refptr<T> and do copies. Yes, that'd be an extra AddRef()/Release() pair :(For non-thread-safe refcounting cases, I thought it was commonly agreed that it'd be in the noise perf-wise (most likely hidden under the previous/next memory access on modern OoO CPUs).For thread-safe, I could see it being a problem in inner loops - is that common though?
On Wed, Oct 31, 2012 at 5:07 PM, Antoine Labour <pi...@google.com> wrote:
On Wed, Oct 31, 2012 at 5:03 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Oct 31, 2012 at 5:02 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Oct 31, 2012 at 4:54 PM, Antoine Labour <pi...@google.com> wrote:
On Wed, Oct 31, 2012 at 4:32 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
So I looked into it. I've uploaded a partial changelist (my clang rewriter crapped out due to some overlapping replacements when we have nested expressions using the implicit operator T*): http://codereview.chromium.org/download/issue11275088_1.diffOne thing I don't like is the stuff like MessageLoopProxy::current().get() or Profile::GetForFactory(foo).get(). Pretty gross if you ask me =/Ignore the if (foo.get()) expressions. I'll fix those with the safe operator bool idiom later.I think to fix this completely, we'd need to either allow |const scoped_refptr<T>&| (I know we disallowed this earlier, but maybe we need to revisit) or introduce pass_scoped_refptr<T> or something.Why? Is it that we don't want to pay for an extra AddRef/Release?Avoids the .get(). Most function parameters are of the form Foo*. If we could change them to const scoped_refptr<Foo>& instead, that'd avoid the caller needing to invoke .get() to pass a Foo*.Oops, I misunderstood. You were assuming we'd change the function parameters to be scoped_refptr<T> and do copies. Yes, that'd be an extra AddRef()/Release() pair :(For non-thread-safe refcounting cases, I thought it was commonly agreed that it'd be in the noise perf-wise (most likely hidden under the previous/next memory access on modern OoO CPUs).For thread-safe, I could see it being a problem in inner loops - is that common though?I agree that performance isn't a large concern in general. Indeed, I am the person who argued we should just make RefCountedThreadSafe the default after all. Do people prefer passing around copies of scoped_refptr instead? That's definitely another option. No one proposed it in the old discussion on const scoped_refptr<T>&, so I was assuming people didn't really consider it. Would you prefer this over const scoped_refptr<T>&?
On Wed, Oct 31, 2012 at 5:07 PM, Antoine Labour <pi...@google.com> wrote:
On Wed, Oct 31, 2012 at 5:03 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Oct 31, 2012 at 5:02 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Oct 31, 2012 at 4:54 PM, Antoine Labour <pi...@google.com> wrote:
On Wed, Oct 31, 2012 at 4:32 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
So I looked into it. I've uploaded a partial changelist (my clang rewriter crapped out due to some overlapping replacements when we have nested expressions using the implicit operator T*): http://codereview.chromium.org/download/issue11275088_1.diffOne thing I don't like is the stuff like MessageLoopProxy::current().get() or Profile::GetForFactory(foo).get(). Pretty gross if you ask me =/Ignore the if (foo.get()) expressions. I'll fix those with the safe operator bool idiom later.I think to fix this completely, we'd need to either allow |const scoped_refptr<T>&| (I know we disallowed this earlier, but maybe we need to revisit) or introduce pass_scoped_refptr<T> or something.Why? Is it that we don't want to pay for an extra AddRef/Release?Avoids the .get(). Most function parameters are of the form Foo*. If we could change them to const scoped_refptr<Foo>& instead, that'd avoid the caller needing to invoke .get() to pass a Foo*.Oops, I misunderstood. You were assuming we'd change the function parameters to be scoped_refptr<T> and do copies. Yes, that'd be an extra AddRef()/Release() pair :(For non-thread-safe refcounting cases, I thought it was commonly agreed that it'd be in the noise perf-wise (most likely hidden under the previous/next memory access on modern OoO CPUs).For thread-safe, I could see it being a problem in inner loops - is that common though?I agree that performance isn't a large concern in general. Indeed, I am the person who argued we should just make RefCountedThreadSafe the default after all. Do people prefer passing around copies of scoped_refptr instead? That's definitely another option. No one proposed it in the old discussion on const scoped_refptr<T>&, so I was assuming people didn't really consider it. Would you prefer this over const scoped_refptr<T>&?
On Wed, Oct 31, 2012 at 5:17 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Oct 31, 2012 at 5:07 PM, Antoine Labour <pi...@google.com> wrote:
On Wed, Oct 31, 2012 at 5:03 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Oct 31, 2012 at 5:02 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
On Wed, Oct 31, 2012 at 4:54 PM, Antoine Labour <pi...@google.com> wrote:
On Wed, Oct 31, 2012 at 4:32 PM, William Chan (陈智昌) <will...@chromium.org> wrote:
So I looked into it. I've uploaded a partial changelist (my clang rewriter crapped out due to some overlapping replacements when we have nested expressions using the implicit operator T*): http://codereview.chromium.org/download/issue11275088_1.diffOne thing I don't like is the stuff like MessageLoopProxy::current().get() or Profile::GetForFactory(foo).get(). Pretty gross if you ask me =/Ignore the if (foo.get()) expressions. I'll fix those with the safe operator bool idiom later.I think to fix this completely, we'd need to either allow |const scoped_refptr<T>&| (I know we disallowed this earlier, but maybe we need to revisit) or introduce pass_scoped_refptr<T> or something.Why? Is it that we don't want to pay for an extra AddRef/Release?Avoids the .get(). Most function parameters are of the form Foo*. If we could change them to const scoped_refptr<Foo>& instead, that'd avoid the caller needing to invoke .get() to pass a Foo*.Oops, I misunderstood. You were assuming we'd change the function parameters to be scoped_refptr<T> and do copies. Yes, that'd be an extra AddRef()/Release() pair :(For non-thread-safe refcounting cases, I thought it was commonly agreed that it'd be in the noise perf-wise (most likely hidden under the previous/next memory access on modern OoO CPUs).For thread-safe, I could see it being a problem in inner loops - is that common though?I agree that performance isn't a large concern in general. Indeed, I am the person who argued we should just make RefCountedThreadSafe the default after all. Do people prefer passing around copies of scoped_refptr instead? That's definitely another option. No one proposed it in the old discussion on const scoped_refptr<T>&, so I was assuming people didn't really consider it. Would you prefer this over const scoped_refptr<T>&?I personally prefer const scoped_refptr<T>&. The extra doesn't matter, but const OCDness here doesn't make much semantic sense to me. The scoped_refptr is really just a carrier. Do we believe there is a true readability downside here? I'm skeptical.
I agree with you. This is what made me a fan of the proposed .get() change. It is just slightly cumbersome, but perhaps that's still the best way to go.
On Wed, Oct 31, 2012 at 11:38 PM, Darin Fisher <da...@chromium.org> wrote:
I agree with you. This is what made me a fan of the proposed .get() change. It is just slightly cumbersome, but perhaps that's still the best way to go.I want to make sure I understand what you mean by the .get() change, and what you prefer it over. Are you simply saying you prefer using get() over having implicit conversion?
As for parameters and return types, I don't see a problem allowing both:a) scoped_refptr<T>b) const scoped_refptr<T>&Use (a) if you know it's not at all performance critical and you want to prefer readability. Use (b) when you might care about performance. I would usually prefer (b)... I don't think the impact on readability is really that high, since most experienced C++ programmers understand the "const-reference" idiom at such a deep level that it doesn't even feel like indirection anymore.
There may be special cases where passing the raw pointer around is the best thing to do. But I think we should discourage that. The basic rules of thumb for smart pointers should be:1) Wrap the object in a smart pointer as soon as it's created (shared_ptr<T> t_ptr = shared_ptr<T>(new T)).2) Never convert it to a raw pointer (unless you have to, e.g. for a third-party API that's not aware of ref-counting).
On Thu, Nov 1, 2012 at 10:53 AM, David Michael <dmic...@google.com> wrote:
On Wed, Oct 31, 2012 at 11:38 PM, Darin Fisher <da...@chromium.org> wrote:
I agree with you. This is what made me a fan of the proposed .get() change. It is just slightly cumbersome, but perhaps that's still the best way to go.I want to make sure I understand what you mean by the .get() change, and what you prefer it over. Are you simply saying you prefer using get() over having implicit conversion?YesAs for parameters and return types, I don't see a problem allowing both:a) scoped_refptr<T>b) const scoped_refptr<T>&Use (a) if you know it's not at all performance critical and you want to prefer readability. Use (b) when you might care about performance. I would usually prefer (b)... I don't think the impact on readability is really that high, since most experienced C++ programmers understand the "const-reference" idiom at such a deep level that it doesn't even feel like indirection anymore.I prefer (b). I always have a gut reaction against passing objects by value, and I prefer to trust my gut. I prefer not having to think about whether it is OK to pass an object by value. Just always pass objects by const ref, and you should be OK unless you are doing something fancy :-)There may be special cases where passing the raw pointer around is the best thing to do. But I think we should discourage that. The basic rules of thumb for smart pointers should be:1) Wrap the object in a smart pointer as soon as it's created (shared_ptr<T> t_ptr = shared_ptr<T>(new T)).2) Never convert it to a raw pointer (unless you have to, e.g. for a third-party API that's not aware of ref-counting).I don't have quite so strong of an opinion on this. Have we been burned a lot by using raw pointers to reference counted types?Even in WebCore, where they have PassRefPtr<T>, they still commonly pass raw pointers to reference counted types into functions.
There may be special cases where passing the raw pointer around is the best thing to do. But I think we should discourage that. The basic rules of thumb for smart pointers should be:1) Wrap the object in a smart pointer as soon as it's created (shared_ptr<T> t_ptr = shared_ptr<T>(new T)).2) Never convert it to a raw pointer (unless you have to, e.g. for a third-party API that's not aware of ref-counting).I don't have quite so strong of an opinion on this. Have we been burned a lot by using raw pointers to reference counted types?Even in WebCore, where they have PassRefPtr<T>, they still commonly pass raw pointers to reference counted types into functions.
On Thu, Nov 1, 2012 at 11:05 AM, Darin Fisher <da...@chromium.org> wrote:
There may be special cases where passing the raw pointer around is the best thing to do. But I think we should discourage that. The basic rules of thumb for smart pointers should be:1) Wrap the object in a smart pointer as soon as it's created (shared_ptr<T> t_ptr = shared_ptr<T>(new T)).2) Never convert it to a raw pointer (unless you have to, e.g. for a third-party API that's not aware of ref-counting).I don't have quite so strong of an opinion on this. Have we been burned a lot by using raw pointers to reference counted types?Even in WebCore, where they have PassRefPtr<T>, they still commonly pass raw pointers to reference counted types into functions.It's somewhat inconsistent, but a convention that I like and that some code sticks to is that you pass a PassRefPtr<T> when you want the force callee to deal with the ref-counted nature of the pointer and use a raw pointer when the callee doesn't necessarily care. I.e. if you are going to take an owning reference of the parameter, take a PassRefPtr<T>. If you aren't retaining the pointer beyond the callstack, take a raw pointer.