[cxx-abi-dev] Do zero-length arrays make a class type non-empty?

John McCall rjmccall at apple.com
Mon Apr 27 20:37:11 UTC 2015


> On Apr 27, 2015, at 1:33 PM, Richard Smith <richardsmith at googlers.com> wrote:
> 
> On 27 April 2015 at 13:23, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> wrote:
> 
>> On Apr 26, 2015, at 2:26 PM, Richard Smith <richardsmith at googlers.com <mailto:richardsmith at googlers.com>> wrote:
>> 
>> On 25 April 2015 at 21:10, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20150427/02bbb3b5/attachment.html>


More information about the cxx-abi-dev mailing list