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

John McCall rjmccall at apple.com
Mon Apr 27 20:23:02 UTC 2015


> On Apr 26, 2015, at 2:26 PM, Richard Smith <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?

> I think that's equivalent, and it seems simpler and more general.
> 
> Another problem is in step 2 of the layout algorithm: "Place D at this offset unless doing so would result in two components (direct or indirect) of the same type having the same offset.". That does the wrong thing for:
> 
>   struct A { int n[0]; int m[0]; };
> 
> where sizeof(A) should be zero, but will be 4 with this algorithm because putting m at offset 0 gives two components of type 'int[0]' at the same offset. Perhaps replace "components (direct or indirect)" with "non-array subobjects"?

That seems reasonable.

John.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20150427/c581bfb3/attachment.html>


More information about the cxx-abi-dev mailing list