[cxx-abi-dev] Passing an empty class by value

Jason Merrill jason at redhat.com
Mon Feb 29 03:26:32 UTC 2016


On 02/27/2016 02:57 AM, Gabriel Dos Reis wrote:
> On Fri, Feb 26, 2016 at 8:01 PM, Jason Merrill <jason at redhat.com> wrote:
>
>> On 12/11/2015 01:37 PM, Jason Merrill wrote:
>>
>>> On 12/10/2015 07:32 PM, Richard Smith wrote:
>>>
>>>> On 10 December 2015 at 16:15, John McCall <rjmccall at apple.com> wrote:
>>>>
>>>> On Dec 10, 2015, at 4:11 PM, Nelson, Clark <clark.nelson at intel.com>
>>>>>>
>>>>> wrote:
>>>>>
>>>>>>
>>>>>> It has come to my attention that GCC and clang generate incompatible
>>>>>> code
>>>>>> for passing an argument of an empty class type.
>>>>>>
>>>>>> clang seems to completely ignore arguments and parameters of empty
>>>>>> class
>>>>>> type -- which seems to make a certain amount of sense.
>>>>>>
>>>>>> OTOH, as far as I understand it, GCC effectively treats an empty class
>>>>>> equivalently to a class containing a single member with some character
>>>>>> type -- which also seems pretty reasonable.
>>>>>>
>>>>>> Should the C++ ABI come down on one side or the other of this question?
>>>>>>
>>>>>> This is really the sort of question a psABI should settle. But of
>>>>>> course
>>>>>> the C language doesn't actually support a structure with no members, so
>>>>>> it's not too surprising if a psABI doesn't nail down what should happen
>>>>>> for this.
>>>>>>
>>>>>
>>>>> It’s valid as a C extension in GCC.  If there are platforms where we
>>>>> use a
>>>>> different rule from GCC, we should come to some understanding with them.
>>>>>
>>>>> Because of the GCC extension, C++ can’t really use different rules
>>>>> from C.
>>>>>
>>>>
>>>>
>>>> (For x86_64:) GCC uses different rules for C and C++. In C, they do not
>>>> pass anything. In C++, they pass a 1-byte object on the stack. Clang uses
>>>> the same rules for C and C++, passing nothing in both cases.
>>>>
>>>> A careful reading of the x86_64 psABI suggests that clang is right in
>>>> both
>>>> cases; the eightbyte corresponding to the 1-byte empty struct
>>>> parameter is
>>>> never classified (at all), so should occupy neither a register nor
>>>> memory,
>>>> but it's not really especially clear.
>>>>
>>>> In any case, I think GCC should be the one to change here, because its C
>>>> and C++ ABIs don't match.
>>>>
>>>
>>> Agreed.
>>>
>>
>> On further discussion, it came up that the C and C++ ABIs really can't
>> match.  In GNU C, an empty struct has size 0; in C++ it has size 1.  We
>> could finesse this difference for argument passing, as suggested here, but
>> we really can't paper over the difference in general.  What if you have a
>> class containing an empty class?  GNU C still says that has size 0, but
>> it's less clear that this makes sense for C++.  Significantly, this does
>> not fit the ABI definition of an empty class.
>
> Five years ago, we determined that it would make sense (read: provably
> safe) to optimize that case too -- even for arrays.  See section 6.2 of
>        http://www.axiomatics.org/~gdr/formal-cxx/layout-popl11.pdf
> for the "layman" summary.

Sure.  But my point is that this represents a change to the ABI, not a 
simple implementation bug as I initially thought.  If we want to omit 
passing some parameters, we need some specification of which parameters 
qualify, and I'm rather uncomfortable with that level of invention at 
this point.

>> I also notice that the ABI says "If the base ABI does not specify rules
>> for empty classes, then an empty class has size and alignment 1."

Jason




More information about the cxx-abi-dev mailing list