<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 3, 2016 at 1:40 PM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron.ballman@gmail.com" target="_blank">aaron.ballman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Wed, Feb 3, 2016 at 4:13 PM, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>> wrote:<br>
><br>
><br>
> On Wed, Feb 3, 2016 at 1:03 PM, Jonathan Coe <<a href="mailto:jon@jbcoe.net">jon@jbcoe.net</a>> wrote:<br>
>><br>
>><br>
>><br>
>> On 3 February 2016 at 18:44, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>> wrote:<br>
>>><br>
>>><br>
>>><br>
>>> On Wed, Feb 3, 2016 at 10:23 AM, Jonathan Coe <<a href="mailto:jon@jbcoe.net">jon@jbcoe.net</a>> wrote:<br>
>>>><br>
>>>> All the C++ compilers I have tried using (GCC,Clang,MSVC) will generate<br>
>>>> assignment operators even if the user defines a copy-constructor. This is<br>
>>>> the behaviour I set out to write a check for.<br>
>>>><br>
>>>> The cpp core guide lines recommend defining all or none of the special<br>
>>>> functions<br>
>>>> <a href="https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c21-if-you-define-or-delete-any-default-operation-define-or-delete-them-all" rel="noreferrer" target="_blank">https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c21-if-you-define-or-delete-any-default-operation-define-or-delete-them-all</a><br>
>>>><br>
>>>> If the deprecation warning you mention will turn off the deprecated<br>
>>>> generation of special member functions when others are defined (or warn when<br>
>>>> deprecated compiler-generated functions are used) then the rule-of-five<br>
>>>> check is of reduced value.<br>
>>><br>
>>><br>
>>> It can't stop them being generated, because that's required behavior -<br>
>>> warnings don't change the program behavior.<br>
>>><br>
>><br>
>> That's true but promoting them to errors will stop compilation and prevent<br>
>> the sort of bug I'm trying to stop.<br>
><br>
><br>
> Sure - and the user can do that with -Werror=deprecated (but, yes, we should<br>
> split out that specific deprecation so it can be turned on without turning<br>
> on other deprecation)<br>
><br>
>><br>
>><br>
>>><br>
>>> Wording like this is in the C++11 standard:<br>
>>><br>
>>> "If the class definition does not explicitly declare a copy constructor,<br>
>>> one is declared implicitly. If the class definition declares a move<br>
>>> constructor or move assignment operator, the implicitly declared copy<br>
>>> constructor is defined as deleted; otherwise, it is defined as defaulted<br>
>>> (8.4). The latter case is deprecated if the class has a user-declared copy<br>
>>> assignment operator or a user-declared destructor."<br>
>>><br>
>><br>
>> The 'deprecated' part is my target. I've seen code with user-defined copy<br>
>> constructors behave badly when compiler-generated assignment operators are<br>
>> unwittingly used.<br>
><br>
><br>
> For sure - because it's only deprecated, not an error. Clang-tidy won't<br>
> change that - it still won't be a hard error in every codebase.<br>
><br>
> I agree that having all the Core Guidelines checks in one place is a good<br>
> idea, so I'm not making any real suggestion here, sorry - just that it seems<br>
> unfortunate to relegate this check (& encourage explicit & mostly redundant<br>
> defaulting/deleting) to a separate tool when it's essentially built into the<br>
> language and compiler already. My disagreement is perhaps more with the Core<br>
> Guideline than with its implementation here.<br>
><br>
>><br>
>> The rule of five lets me locally reason about code without having to worry<br>
>> (needlessly or not) about whether some functions are potentially being<br>
>> compiler-generated.<br>
><br>
><br>
> But once the language does the right thing directly, rather than providing a<br>
> clang-tidy warning that encourages you to change the code to achieve the<br>
> same result, why would we worry about being explicit?<br>
<br>
</div></div>It could be argued that implicit code generated by the compiler is<br>
magic, and being explicit is a readability improvement. You no longer<br>
have to think "under what circumstances is this generated?" </blockquote><div><br>Except this rule doesn't argue that - if all the members are implicit that is acceptable to this rule (even if the implicit special members are entirely non-trivial because one of the member variables has non-trivial special members). The issue is about implicit code when at least one of them is explicit.<br><br>Except that doesn't happen in C++11 (except in the two deprecated cases) - there is no implicit code to be worried about except for historic (and deprecated - I agree, we could do better there*) reasons. New C++ programmers won't need to be taught the rule of 5 - the language will just DTRT. I'm not sure it's necessarily an improvement to create coding conventions for that sort of historic reason.<br><br>* but 'better' might just be separating out that deprecation warning and enabling it as a clang-tidy warning in the core guidelines group<br><br>- Dave</div></div></div></div>