如果该类包含作为第一个元素的基类类型的成员,然后是其他成员,则编译器是否可以优化空基数? [英] Can the compiler optimize out the empty base if the class contains a member of base class type as first element, followed by other members?

查看:56
本文介绍了如果该类包含作为第一个元素的基类类型的成员,然后是其他成员,则编译器是否可以优化空基数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑:

struct empty {};
struct child : empty {
    empty a[sizeof(int) / sizeof(empty)];
    int b;
};
// Assume sizeof(int) >= sizeof(empty)

sizeof(child)的标准要求是否大于 2 * sizeof(int)?

Does the standard mandate that sizeof(child) is more than 2 * sizeof(int)?

我的看法是,没有什么可以阻止基类子对象与成员 b 共享其地址.

The way I see it, nothing prohibits the baseclass-subobject from sharing its address with member b.

如果没有,那么是否有任何通用的ABI可以利用它?

If not, are there any common ABIs exploiting that at all?

推荐答案

让我们首先检查允许空基类优化使自己熟悉术语的规则:

Let us first check the rule that allows empty base class optimization to acquaint ourselves with the terminology:

N4659标准草案[介绍对象]

N4659 standard draft [intro.object]

7除非是位域(12.2.4),否则派生最多的对象的大小应为非零,并且应占据一个或多个存储字节数.基类子对象的大小可能为零.[snip]

7 Unless it is a bit-field (12.2.4), a most derived object shall have a nonzero size and shall occupy one or more bytes of storage. Base class subobjects may have zero size. [snip]

然后有一个关于不同地址的要求:

Then a requirement about distinct addresses:

8除非对象是位域或大小为零的基类子对象,否则该对象的地址为地址占用的第一个字节的字节数.生命周期重叠且不是位域的两个对象a和b可能具有如果一个地址嵌套在另一个地址中,或者至少一个是大小为且为零的基类子对象,并且它们是不同类型的;否则,它们有不同的地址.

8 Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first byte it occupies. Two objects a and b with overlapping lifetimes that are not bit-fields may have the same address if one is nested within the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they have distinct addresses.

空的基础子对象和成员数组的第一个元素可能不具有相同的地址,因为它们的类型相同.

The empty base subobject and the first element of the member array may not have the same address because they are of same type.

因此,如果我们假设必须在成员之前对基本子对象进行排序,并且成员必须处于声明顺序,则需要填充以实现不同的地址.但是,我在标准中找不到需要这种顺序的规则.

Therefore, if we assume that the base subobject must be ordered before the members and that the members must be in declaration order, padding is required to achieve distinct addresses. However, I cannot find a rule in the standard that would require such order.

便携式 Itanium C ++ ABI(由Clang和GCC使用)确实指定了顺序,并且在该规范下,确实需要填充:

The portable Itanium C++ ABI (used by Clang and GCC) does specify the order, and under that specification, padding is indeed required:

2.4非POD类类型

2.4 Non-POD Class Types

II.虚拟基地以外的成员分配

II. Allocation of Members Other Than Virtual Bases

对于每个数据组件D(首先是C的主基,如果有的话,然后是按声明顺序的非主,非虚拟直接基类,然后是按声明顺序的非静态数据成员和未命名的位域),分配如下:

For each data component D (first the primary base of C, if any, then the non-primary, non-virtual direct base classes in declaration order, then the non-static data members and unnamed bitfields in declaration order), allocate as follows:

如果不同的ABI允许在内存布局的基数之前允许非声明顺序子对象或成员子对象,则这里可以使用EBCO.至少作为空基的特殊情况.我不知道这样的ABI是否存在.

A different ABI might be able to exploit EBCO here, if it allows non-declaration order sub-objects or member subobjects before bases in the memory layout. At least as a special case with empty bases. I don't know if such ABI exist.

这篇关于如果该类包含作为第一个元素的基类类型的成员,然后是其他成员,则编译器是否可以优化空基数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆