[cxx-abi-dev] Passing an empty class by value
Jason Merrill
jason at redhat.com
Sat Feb 27 04:01:38 UTC 2016
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.
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