如果该类包含作为第一个元素的基类类型的成员,然后是其他成员,则编译器是否可以优化空基数? [英] 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?
问题描述
考虑:
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屋!