如果类包含基类类型的成员作为第一个元素,然后是其他成员,编译器可以优化空基吗?

2024-03-16

考虑:

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

标准是否强制要求sizeof(child)超过2 * sizeof(int)?

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

如果没有,是否有任何常见的 ABI 可以利用它?


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

N4659 标准草案 [intro.object]

7 除非它是位字段(12.2.4),否则最派生对象应具有非零大小,并应占用一个或多个 字节存储。基类子对象的大小可能为零。 [剪]

然后是关于不同地址的要求:

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

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

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

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

2.4 非 POD 类类型

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

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

如果不同的 ABI 允许内存布局中的基数之前有非声明顺序子对象或成员子对象,则它可能能够在此处利用 EBCO。至少作为空基地的特殊情况。我不知道这样的ABI是否存在。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果类包含基类类型的成员作为第一个元素,然后是其他成员,编译器可以优化空基吗? 的相关文章

随机推荐