--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To post to this group, send email to c...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAF52%2BS4x0qQS1zvuJV8%3D5KqSG4R-wQV9DHhNS%3Dcz1SnQg9jj-A%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAJ_4DfR8G9z6kiVuq3BUHZGLD1fgXrrMTZgoAFNmBOPnVN3FGA%40mail.gmail.com.
Oh, one other thing I forgot to mention: scoped_ptr<T> currently has make_scoped_ptr. For unique_ptr, there are several options:
- Add a WrapUnique helper:
auto p = WrapUnique(new RenderWidgetHostViewDelegateClientFactoryHelper(delegate, client));
Why not call it make_unique_ptr? As it turns out, C++14 already has std::make_unique which has different semantics. This leads us to option...- Add a MakeUnique helper that does the same thing as C++14's std::make_unique.
auto p = MakeUnique<RenderWidgetHostViewDelegateClientFactoryHelper>(delegate, client);
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAF3XrKqFW91hRr1smPnDjJbxPF9YSFqFnrRy9C9as%2BL%2BavD9Hg%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAF3XrKqFW91hRr1smPnDjJbxPF9YSFqFnrRy9C9as%2BL%2BavD9Hg%40mail.gmail.com.
On Thu, Nov 12, 2015 at 2:24 PM, Nico Weber <tha...@chromium.org> wrote:
> I too think it makes sense to handle unique_ptr and shared_ptr separately.
+1.
> I suppose shared_ptr is morally equivalent to scoped_refptr, so we'd need to
> have some story around these two classes like we do for unique_ptr /
> scoped_ptr.
There are some efficiency differences between shared_ptr and
scoped_refptr, which should be explored in the proposal to allow
shared_ptr. e.g. sizeof(shared_ptr)>sizeof(scoped_refptr), and
enable_shared_from_this also has overhead.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CANh-dXntiTqm%2Baq6RkC9To5C4hrOwWAZqc-u1rscVjLBDz_gHg%40mail.gmail.com.
On Thu, Nov 12, 2015 at 2:28 PM, Jeffrey Yasskin <jyas...@chromium.org> wrote:On Thu, Nov 12, 2015 at 2:24 PM, Nico Weber <tha...@chromium.org> wrote:
> I too think it makes sense to handle unique_ptr and shared_ptr separately.
+1.
> I suppose shared_ptr is morally equivalent to scoped_refptr, so we'd need to
> have some story around these two classes like we do for unique_ptr /
> scoped_ptr.
There are some efficiency differences between shared_ptr and
scoped_refptr, which should be explored in the proposal to allow
shared_ptr. e.g. sizeof(shared_ptr)>sizeof(scoped_refptr), and
enable_shared_from_this also has overhead.Yah. My general feelings are that:1) I don't like using types in std:: that provide the same things as types in base::. Using different "standardish" types in different places feels awkward and confusing.2) I prefer using types in std:: to having our own implementation of it in base:: when possible.All that is to say, I don't feel excited about allowing std::shared_ptr while we also have scoped_refptr.And I enthusiastically welcome data-driven proposals around replacing scoped_refptr with std::shared_ptr if this turns out to be reasonable.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAHtyhaRQdfH0u-CeHsQSL9NJUuQerz_8-p%2Bwb-H405o0Y1%3D%2B_g%40mail.gmail.com.
All that is to say, I don't feel excited about allowing std::shared_ptr while we also have scoped_refptr.
I think we should have a single guideline for stuff in src.git, else things will get super confusing.
I too think it makes sense to handle unique_ptr and shared_ptr separately.Allowing unique_ptr early makes sense to me (for quic if nothing else), and https://codereview.chromium.org/1432193002/ seems like a good way to get there.WrapUnique() also sounds good to me. Is it feasible to mass-replace "make_scoped_ptr" to "wrap_scoped_ptr" to keep names similar? (/me shakes fist at standard for giving make_unique gratuitously different behavior than make_pair etc).I suppose shared_ptr is morally equivalent to scoped_refptr, so we'd need to have some story around these two classes like we do for unique_ptr / scoped_ptr.
Forking this since this discussion is largely about shared_ptr.
My gut response is that I don't like shared_ptr and I'd prefer not to allow it now. One big thing we do with our RefCounted class is allow it to express which thread it should be deleted on. This is pretty important to us, so I don't think we can remove our own RefCounted class.
On Thu, Nov 12, 2015 at 3:13 PM, Nico Weber <tha...@chromium.org> wrote:I think we should have a single guideline for stuff in src.git, else things will get super confusing.So we need to split sandbox/linux into bauxite.git to be able to use std::shared_ptr?
I think we should consider std::shared_ptr separately.I had a draft for std::unique_ptr, but since the thread already started, I'll just dump it here instead. std::unique_ptr is blocked on std::move(), since it's not as useful without it. A few things that I think are worth highlighting:
- converting between std::unique_ptr and scoped_ptr: in order to allow people to start using it incrementally, it's probably useful to have a way to convert back and forth between them. https://codereview.chromium.org/1432193002 is a proposal that would allow this.
- std::unique_ptr and base::Bind: base::Bind() and base::Passed() depends on the custom macros for move semantics, which add a Pass() member to movable types. One option is to use template metaprogramming magic to make base::Passed() magically use std::move() for types with move constructors/operators. Another is to add more magic to base::Bind() so it can implicitly convert std::unique_ptr to scoped_ptr.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAF3XrKr3LT1xQT9t6aMbKepPRb6UbGUy6rpfomLG6QEhMHQJhA%40mail.gmail.com.
On Thu, Nov 12, 2015 at 1:15 PM, Daniel Cheng <dch...@chromium.org> wrote:I think we should consider std::shared_ptr separately.I had a draft for std::unique_ptr, but since the thread already started, I'll just dump it here instead. std::unique_ptr is blocked on std::move(), since it's not as useful without it. A few things that I think are worth highlighting:
- converting between std::unique_ptr and scoped_ptr: in order to allow people to start using it incrementally, it's probably useful to have a way to convert back and forth between them. https://codereview.chromium.org/1432193002 is a proposal that would allow this.
- std::unique_ptr and base::Bind: base::Bind() and base::Passed() depends on the custom macros for move semantics, which add a Pass() member to movable types. One option is to use template metaprogramming magic to make base::Passed() magically use std::move() for types with move constructors/operators. Another is to add more magic to base::Bind() so it can implicitly convert std::unique_ptr to scoped_ptr.
(IIRC this doesn't work well because move constructors don't guarantee to zero out the moved-from object. It's true for scoped_ptr and I think unique_ptr and hopefully our move-emulated objects we currently have, but not for all movable types in general.)
On Thu, Nov 12, 2015 at 4:07 PM, Peter Kasting <pkas...@google.com> wrote:On Thu, Nov 12, 2015 at 3:16 PM, Daniel Cheng <dch...@chromium.org> wrote:Forking this since this discussion is largely about shared_ptr.Brett responded about shared_ptr directly in the original thread, but I'm moving my response to him here to try and keep shared_ptr stuff in this thread.On Thu, Nov 12, 2015 at 3:52 PM, Brett Wilson <bre...@chromium.org> wrote:My gut response is that I don't like shared_ptr and I'd prefer not to allow it now. One big thing we do with our RefCounted class is allow it to express which thread it should be deleted on. This is pretty important to us, so I don't think we can remove our own RefCounted class.I worry a bit about code that does this, though. In most of the cases I've seen, use of this functionality actually means that the code isn't sufficiently robust against some set of circumstances, and Bad Things can happen. (I'm being vague because it's been a little while so I can't remember the details of specific examples.)I'm of two minds here. On one hand, I would really prefer to use the STL if at all possible and avoid our own classes that basically tackle the same problem. For this reason, I really would prefer shared_ptr over scoped_refptr etc. as long as there's not a significant performance loss.On the other hand, I kind of like that today you can't refcount a class unless the class allows it by inheriting from RefCounted. It helps prevent people from refcounting in general, which is an explicit goal. shared_ptr's ability to make anything refcounted seems like an invitation to bugginess. This makes me want to disallow it.Yeah, philosophically, I think it's important to be able to know by looking at the class what type of memory management it expects.
As an example, one of the big things we use RefCounted for is for posting work to a background thread (among other options for using Bind). But if this became shared_ptr to keep the object alive across the post, it becomes too easy to screw up the memory management and using both manual deleting + shared_ptr (if my understanding of shared_ptr is correct. Our RefCounted class has a lot of protections that tell you right away when you screw up.Brett
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To post to this group, send email to c...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CABiGVV9Vnsi5sgMo5kfEcgT9Tku4r5cxD6uCN4QCPZ_HhpY%2BeA%40mail.gmail.com.
- James
Daniel- James
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To post to this group, send email to c...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAF3XrKrbhiX9knK%2BJzK3A46Jbup0RwZa2rW10Bc7XY4Ca2fc2g%40mail.gmail.com.
On the other hand, I kind of like that today you can't refcount a class unless the class allows it by inheriting from RefCounted. It helps prevent people from refcounting in general, which is an explicit goal. shared_ptr's ability to make anything refcounted seems like an invitation to bugginess. This makes me want to disallow it.
As a separate point, we also have some code that starts out with a scoped_refptr, then passes a raw pointer down somewhere and whatever class receives the raw pointer puts it in another scoped_refptr. That's fine when ref counting is done in the class, but with shared_ptrs, if I'm not mistaken, this is going to cause a double free, since two blocks of ref counting would be allocated. I think if we lean towards allowing shared_ptr, then we at least need an audit of current usages first.
On the other hand, I kind of like that today you can't refcount a class unless the class allows it by inheriting from RefCounted. It helps prevent people from refcounting in general, which is an explicit goal. shared_ptr's ability to make anything refcounted seems like an invitation to bugginess. This makes me want to disallow it.I agree with discouraging ref counting in general. And I understand that making ref counting more difficult can be a very very good way to discourage it. However, I strongly dislike the idea of any type not related to memory management having to deal with memory management. Especially when it involves inheritance. Imagine if you could not put an int on the stack because it was ref counted in some case. So instead either all ints are ref counted or we have two types (one for ref counted and one not). Neither of these options is good and it stems from the type assuming too much about its usage. Let the type care only about the one thing it should care about. Compositing restrictions for each usage is much easier (I need an int and I need it ref counted).
Given these two evils, I feel like shared_ptr is the lesser.
As a separate point, we also have some code that starts out with a scoped_refptr, then passes a raw pointer down somewhere and whatever class receives the raw pointer puts it in another scoped_refptr. That's fine when ref counting is done in the class, but with shared_ptrs, if I'm not mistaken, this is going to cause a double free, since two blocks of ref counting would be allocated. I think if we lean towards allowing shared_ptr, then we at least need an audit of current usages first.
This sounds to me like a problem that should be fixed.
It sounds like it happens to work now because the type has the ref count baked in. But the design requires it be ref counted and doesn't explicitly state that. It relies on the type to enforce that.
Since the design requires the type be ref counted, it could explicitly state that by taking a shared_ptr instead of a raw pointer.
+1, I very much dislike having to decide whether a class should be ref counted or not when writing the class itself, instead of when deciding (or changing) its usage later.
On Wed, Nov 18, 2015 at 11:03 AM, Ryan Sleevi <rsl...@chromium.org> wrote:On Wed, Nov 18, 2015 at 10:59 AM, 'Vladimir Levin' via cxx <c...@chromium.org> wrote:+1, I very much dislike having to decide whether a class should be ref counted or not when writing the class itself, instead of when deciding (or changing) its usage later.Given the sheer number of reference counting issues I've seen - either through incoming reviews or bugs that make it out - I would argue that "deciding whether a class should be ref-counted or not" is very much a decision you should be making up front, at the design time, because it materially affects everything around it.
Switching to reference counting later is almost _always_ an anti-pattern, and using reference counting early in your design is... well, almost always an anti-pattern too :)At the risk of "+1/-1" wars, this is as much an intentional design decision as could be, no different than deciding whether or not you want to allow inheritance, whether to make your class concrete or an interface, whether or not it's a 'public' or 'private' API, and all of the other attendant software design issues.Yea, I fear having every individual programmer decide at time of use whether a given class should be refcounted or not will be disastrous. I think reference counting generally works OK in Chrome today.
Brett
On the other hand, I kind of like that today you can't refcount a class unless the class allows it by inheriting from RefCounted. It helps prevent people from refcounting in general, which is an explicit goal. shared_ptr's ability to make anything refcounted seems like an invitation to bugginess. This makes me want to disallow it.I agree with discouraging ref counting in general. And I understand that making ref counting more difficult can be a very very good way to discourage it. However, I strongly dislike the idea of any type not related to memory management having to deal with memory management. Especially when it involves inheritance. Imagine if you could not put an int on the stack because it was ref counted in some case. So instead either all ints are ref counted or we have two types (one for ref counted and one not). Neither of these options is good and it stems from the type assuming too much about its usage. Let the type care only about the one thing it should care about. Compositing restrictions for each usage is much easier (I need an int and I need it ref counted).
Refcounted classes in Chromium are almost always at the other end of those scales. They hold complex functionality and they are usually used in a limited set of circumstances. Being refcounted often affects class design choices like how deletion happens or what needs locking. For all these reasons, it generally makes sense for the question of refcounting to not be decoupled from the class design.
Refcounted classes in Chromium are almost always at the other end of those scales. They hold complex functionality and they are usually used in a limited set of circumstances. Being refcounted often affects class design choices like how deletion happens or what needs locking. For all these reasons, it generally makes sense for the question of refcounting to not be decoupled from the class design.To give a concrete example: here an instance could have been stack allocated perfectly well, but because the class is refcounted it now incurs a heap allocation.
I assume these bugs were using our current ref counting methods? If that's the case, then maybe it's a case for changing the current system. :)
On a more serious note, I agree that ref counting is hard and it should be used rarely and carefully. I just feel that baking that knowledge into the class at the get-go is not good. If someone decides that a class has to be ref counted, that forces all callers to use refcounting.
Even if those callers would otherwise prefer to create a scoped_ptr instead.
I'm not sure I understand why it would be disastrous. Can you elaborate? If the caller is the one that's creating the object then presumably the caller knows why it's creating the object and it knows whether that particular object should be ref counted.
As mentioned earlier, the class itself can guide (or rather force) the caller by exposing a create function that returns a shared_ptr (which I think is pretty important when the class is using shared_from_this).The problem, as cblume mentioned, is that if there are situations where you want one object not to ref count and the other one to ref count. Right now that's only possible with necessarily ref counting and having a ref count of 1.
It works, but it doesn't specify intent very well. (As a disclaimer, I don't actually have specific examples of these situations)
I'm not sure I understand why it would be disastrous. Can you elaborate? If the caller is the one that's creating the object then presumably the caller knows why it's creating the object and it knows whether that particular object should be ref counted.In practice, this tends to work out extremely poorly.A classic example it's let's imagineclass Foo {public:Foo(Bar* bar, Baz* baz);};This tells you some things about lifetime management, but not everything.The immediate read should be that "Bar and Baz should remain valid for at least as long as the constructor, but likely as long as the object"If that was perhaps implicitly guaranteed in some way - for example, if Baz was having ownership transferred, your reviewer should push on you to make that clearer:Foo(Bar* bar, scoped_ptr<Baz> baz);But we at least know that absent other information, Bar MUST remain valid for the duration of Foo. There's a tight coupling of those lifetimes.Now, regardless of whether you're using RefCounted or shared_ptr<>, the only way to safely use 'foo' is to ensure that everything that may take a reference to Foo outlives Bar. That's hard. Hard for people and hard for machines to guarantee