[cxx-abi-dev] Non-trivial move constructor
John McCall
rjmccall at apple.com
Thu Feb 25 06:41:06 UTC 2016
> On Feb 24, 2016, at 1:14 PM, Richard Smith <richardsmith at googlers.com> wrote:
> On 24 February 2016 at 12:56, John McCall <rjmccall at apple.com> wrote:
>>> On Feb 24, 2016, at 11:43 AM, Richard Smith <richardsmith at googlers.com> wrote:
>>> On 24 February 2016 at 05:54, Jason Merrill <jason at redhat.com> wrote:
>>>> On 02/24/2016 05:51 AM, Marc Glisse wrote:
>>>>>
>>>>> in 3.1.1, we use "In the special case where the parameter type has a
>>>>> non-trivial copy constructor or destructor" to force passing by
>>>>> reference. It seems that for C++11, this should also include move
>>>>> constructors, for the same reasons.
>>>>
>>>>
>>>> We talked about adding move constructors to that sentence years ago. Did it
>>>> never make it into the spec?
>>>
>>> Looks like it didn't. The rule we ended up with was:
>>>
>>> "[Pass an object of class type by value if] every copy constructor and
>>> move constructor is deleted or trivial and at least one of them is not
>>> deleted, and the destructor is trivial.”
>>>
>>>
>>> However, this seems overly-cautious to me; it would seem sufficient
>>> for there to be at least one copy or move constructor that is trivial
>>> and not deleted, and a trivial destructor. It's not really
>>> particularly plausible for there to be a trivial copy and a
>>> non-trivial move or vice versa, but it *is* plausible for there to be
>>> two non-deleted copy constructors -- a trivial one, and one that takes
>>> a const volatile reference -- and in that case, passing through
>>> registers seems completely reasonable. How about changing the rule in
>>> 3.1.1 bullet 1 to:
>>>
>>> "In the special case where the parameter type does not have both a
>>> trivial destructor and at least one trivial copy or move constructor
>>> that is not deleted, the caller must allocate space for a temporary
>>> copy, and pass the resulting copy by reference (below). Specifically
>>> […]"
>>
>> I agree with your proposal in theory, but I’m concerned about changing
>> the ABI at this point. We *are* talking about the language standard that was
>> released six years ago, and an area of that standard that was theoretically
>> fully implemented by compilers several years before that.
>>
>> Do we understand the scope of the ABI disagreement between GCC and Clang here?
>> What do other compilers do?
>
> Clang's rule is the one in the ABI: a class is passed indirectly if it
> has a non-trivial destructor or a non-trivial copy constructor. This
> rule definitely needs some adjustment, because it's not meaningful to
> ask whether an implicitly-deleted function is trivial.
That sounds like it’s on us to fix. Do GCC and other compilers correctly
implement the rule that we agreed on? If so, I’ll go ahead and apply
the change to the ABI document, and we should fix this in clang.
John.
More information about the cxx-abi-dev
mailing list