--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
+1 to allowing default, in particular for your Use Case 1 and Use Case 2.I'm not swayed by use case 3, and I don't condone using default for this Use Case 3. In general, I'd rather let the compiler decide. When this came up before, we found that doing it saved some binary size on GCC and increased binary size on clang. I don't think anybody ever tried it for MSVS. We shouldn't add code complexity in order to get small space savings on 1 toolchain....if we find out that it's a more clear win, we can re-evaluate.
--/Daniel
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev...@chromium.org.
I'd like to wait with this, since explicitly defaulted move constructors don't work right in MSVS2013 ( http://msdn.microsoft.com/en-us/library/hh567368.aspx#defaultedanddeleted ).
On Wed, Sep 24, 2014 at 8:47 AM, Daniel Bratell wrote:
On Wed, Sep 24, 2014 at 8:47 AM, Daniel Bratell <bra...@opera.com> wrote:On Wed, 24 Sep 2014 17:15:57 +0200, David Michael <dmic...@chromium.org> wrote:+1 to allowing default, in particular for your Use Case 1 and Use Case 2.I'm not swayed by use case 3, and I don't condone using default for this Use Case 3. In general, I'd rather let the compiler decide. When this came up before, we found that doing it saved some binary size on GCC and increased binary size on clang. I don't think anybody ever tried it for MSVS. We shouldn't add code complexity in order to get small space savings on 1 toolchain....if we find out that it's a more clear win, we can re-evaluate.That is why I wrote that that use case was for carefully selected places. For instance adding explicit constructors in Angle made the binary 200 KB smaller (10-20% of that whole subproject?). With =default it would have been only a few lines of code.The list in the bug was just a list of suspiciously large code in collections and each one would have had to be analyzed to see if something should be done and what that would be in that case.Binary size has a very low priority (after features, maintainability, performance) for the general chromium project but that doesn't mean code efficiency is completely irrelevant, and with =default the maintenance cost of some changes is greatly reduced which is a good thing.In general, we already require nontrivial constructors (and destructors) to be defined out of line. For default constructors (and destructors), "= default" isn't very compelling. But it's mostly advantageous for copy constructors.
--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev...@chromium.org.
That article does not say that =default on move constructors does not compile, it says that they don't work correctly. That's a big difference. Having code that works on some platforms and miscompiles on MSVS is very bad and hard to discover.
Use case 1:Sometimes you need a trivial default constructor but it will not be automatically generated if there is another constructor. Using =default allows you to create the trivial default constructor without actually implementing it yourself (and if you implement it yourself it will no longer have a chance to be "trivial" from a language perspective).struct A{A() = default;
Use case 2:A(int) { m_1 = "Hello"; }std::string m_1;};Generated constructors/operators are public. Only chance to make them private or protected is to write them yourself. Using =default you can change the accessibility of them without actually having to write any code.struct A{A* createA() { return new A(); }private:// Make it impossible to put A object on the stack.A() = default;A(const A&) = default;
Use case 3:std::string m_1;};The default functions are by default set to be inlined (a hint a compiler can choose to follow (always in gcc) or ignore (often in clang)) so that if a class is large you may need to manually write the operators outline to avoid that. That has a certain cost and risk that might make it hard choice. Also, if you write them yourself a compiler can't ever know that they are "trivial" and can't do certain other optimizations.
On Wed, Sep 24, 2014 at 6:09 AM, Daniel Bratell <bra...@opera.com> wrote:Use case 1:Sometimes you need a trivial default constructor but it will not be automatically generated if there is another constructor. Using =default allows you to create the trivial default constructor without actually implementing it yourself (and if you implement it yourself it will no longer have a chance to be "trivial" from a language perspective).struct A{A() = default;Writing "A() {};" is fewer characters and clearer.
Use case 2:A(int) { m_1 = "Hello"; }std::string m_1;};Generated constructors/operators are public. Only chance to make them private or protected is to write them yourself. Using =default you can change the accessibility of them without actually having to write any code.struct A{A* createA() { return new A(); }private:// Make it impossible to put A object on the stack.A() = default;A(const A&) = default;You can accomplish this today by just declaring A() private and giving it a definition. Again, A() {} is fewer characters.
This is only really important for copy constructors and assignment operators, since the body of a trivial constructor or destructor is trivial to write. I don't think we have enough copy constructors to make this a big issue in our codebase.
And this doesn't compile anymore, because DISALLOW_COPY_AND_ASSIGN() provides non-default constructor which disables the default one.To fix this:class Foo {public:Foo() = default;
I agree, though by having a user defined constructor it can no longer be "trivial" which means that some compiler/library optimizations get disabled.
We don't have many hand written copy constructors or assignment operators but I think there is somewhere in the order of MB of generated ones inlined in the machine code. STL containers, algorithms and our own STL inspired containers and template code love copying and assigning objects. I don't say that this is wrong. If an object has to move from one place in the memory to another, then there has to be machine code that does that. I am just challenging the idea that we don't have many of them.
But if I understand your argument (please correct me if I've misunderstood it), it is that you don't think =default should be allowed because there are other ways to accomplish a similar behaviour and that the places where it would be useful would be few and having =default would be confusing/distracting to people reading the code?
I can agree that it is one of the new things in C++ that not everyone will know immediately (I didn't know about it until 9 months ago when I realised I needed it. :-) ), but I argue that it is way easier to understand than most language features.
/Daniel
I agree, though by having a user defined constructor it can no longer be "trivial" which means that some compiler/library optimizations get disabled.Examples?
I agree, though by having a user defined constructor it can no longer be "trivial" which means that some compiler/library optimizations get disabled.Examples?
Here is a very contrived example:
...
And this is NOT movable (user-provided default constructor kills generated move constructor/assignment operator).
On Wed, Sep 24, 2014 at 11:45 AM, Daniel Bratell <bra...@opera.com> wrote:I agree, though by having a user defined constructor it can no longer be "trivial" which means that some compiler/library optimizations get disabled.Examples?
That's a general argument and not very useful in the concrete. This thread is about a concrete feature and we should consider the concrete pros and cons of it.
That's pretty much completely irrelevant since we can't take advantage of move semantics in STL (since we don't use a library that supports C++11) or in our code (since we don't have std::move() or allow any use of rvalue semantics).
OK, if we could make that consistent across all platforms then it'd be slightly better. But that means =default is only really useful for copy constructors, which we don't tend to have a ton of. Are there examples in our codebase today of copy constructors that we would rather =default?
Writing "A() {};" is fewer characters and clearer.
--
Having different rules for copy vs move that are different from the Google C++ style guide seems worse than having a simpler rule "don't use =default for constructors".
--
Having different rules for copy vs move that are different from the Google C++ style guide seems worse than having a simpler rule "don't use =default for constructors". The most useful thing to advance this proposal would be to advance our toolchains.
It's not totally clear to me from above: do we actually have problems with =default when we're not writing explicit move constructors? If not, given that move constructors are currently banned anyway, can we just use the standard Google style rules for =default? I feel like most of the contention above is about cases that are actually miscompiled.
I don't really care about "A() {}" vs "A() = default" (and Alex's last post seems to have good points in favor of the latter, though I haven't fully digested it yet); I just want to stop having to implement and maintain copy operations myself when the compiler can trivially do it for me.Matthew explained to me that http://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Copyable_Movable_Types explicitly says that copyable types should have explicit copy constructors and assignment operators. Chromium code seems to apply to this rule pretty well, so allowing =default for this makes sense to me. I personally don't see a big advantage of `A() = default` over `A() {}`, but I don't think we need to let the guide make a recommendation on this. Matthew, can you send a CL to move =default (and =delete, while we're at it, I suppose) up to allowed?