> On Apr 27, 2015, at 1:33 PM, Richard Smith <[email protected]> wrote:
>
> On 27 April 2015 at 13:23, John McCall <[email protected]
> <mailto:[email protected]>> wrote:
>
>> On Apr 26, 2015, at 2:26 PM, Richard Smith <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> On 25 April 2015 at 21:10, John McCall <[email protected]
>> <mailto:[email protected]>> wrote:
>> The standard says that std::is_empty<T>::value is true if:
>> - T is a class type, but not a union type, with no non-static data members
>> other than bit-fields of length 0, no virtual member functions, no virtual
>> base classes, and no base class B for which is_empty<B>::value is false.
>>
>> The standard also says that array bounds must be greater than zero, but
>> there’s a common extension to permit zero-length array types (hereafter,
>> ZLATs).
>>
>> In GCC and Clang, at least, a ZLAT conventionally has size 0, both formally
>> (as a result of sizeof) and for struct layout (a ZLAT field takes up no
>> direct space, although it does cause the next offset to be rounded up to the
>> field’s alignment). Moreover, a ZLAT field inhibits the general rule
>> rounding a class's size up to at least 1, recursively.
>>
>> Oddly, though, GCC and Clang also say that a struct containing a ZLAT is not
>> empty, at least as far as std::is_empty is concerned. On the other hand,
>> ICC says that a struct containing only one (or more) ZLATs is empty; as does
>> MSVC, for what it’s worth.
>>
>> This touches on the ABI because:
>> - the results of these metaprogramming traits can affect the ABI in a
>> number of ways,
>> - class sizes are also obviously ABI, and
>> - whether a base class is empty dramatically affects Itanium class layout.
>>
>> The current Itanium definition mirrors the std::is_empty definition:
>> [a] class with no non-static data members other than zero-width bitfields,
>> no virtual functions, no virtual base classes, and no non-empty non-virtual
>> proper base classes.
>>
>> Now, of course, this is an extension, and we don’t have to standardize
>> behavior on it; but my preference is to specify this sort of common
>> extension wherever possible.
>>
>> The point of is_empty is to allow detection of EBO opportunities, so I think
>> it should return 'true' in all cases where EBO would apply. It seems
>> reasonable (if not very worthwhile) to ignore ZLATs when determining whether
>> we can apply EBO. And I think this is a common enough extension for the ABI
>> to specify how it should behave.
>>
>> I propose the following changes:
>>
>> 1. Add “or members of zero-length array type” to the ABI definition of
>> "empty class”.
>>
>> Is it worth explicitly calling out that flexible array members and
>> zero-length array members are handled the same in this regard?
>
> Yes, that’s probably a good idea.
>
>> 2. Specify std::is_empty to behave as if the same clause were there.
>> 3. Change the ABI class layout rule (in IV. Finalization) to not require
>> sizeof(C) to be non-zero if C contains a ZLAT subobject. That is, replace
>> this sentence:
>> Round sizeof(C) up to a non-zero multiple of align(C).
>> with:
>> If C does not contain (recursively) a subobject of zero-length array type,
>> and sizeof(C) is 0, set sizeof(C) to align(C); otherwise, round sizeof(C) up
>> to a multiple of align(C).
>>
>> Perhaps:
>>
>> If sizeof(C) is 0 and C has no non-static data members and no base classes,
>> set sizeof(C) to align(C); otherwise, round sizeof(C) up to a multiple of
>> align(C).
>
> Wouldn’t this trigger for a class with an empty base?
>
> For an empty base class D of class C, step 3 says:
>
> "Once offset(D) has been chosen, update sizeof(C) to max (sizeof(C),
> offset(D)+sizeof(D)) and align(C) to max (alignof(C), nvalign(D))."
>
> So sizeof(C) == sizeof(D) in the case of an otherwise-empty class with one
> base class. Thus sizeof(C) == alignof(C) if D's size was made non-zero, and
> is 0 otherwise (if D had a ZLAT member).
Ah, okay, makes sense.
John.
_______________________________________________
cxx-abi-dev mailing list
[email protected]
http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev