Per*_*-lk 5 c++ inheritance padding abi
相关问题:标准布局和尾部填充
片段:
#include <iostream>
#include <type_traits>
struct A0
{
int a;
char c;
};
struct B0 : A0
{ char d; };
struct A1
{
int a;
private:
char c;
};
struct B1 : A1
{ char d; };
struct A2
{
private:
int a;
char c;
};
struct B2 : A2
{ char d; };
int main()
{
std::cout << std::is_pod<A0>::value << ' ' << sizeof(B0) << std::endl; // 1 12
std::cout << std::is_pod<A1>::value << ' ' << sizeof(B1) << std::endl; // 0 8
std::cout << std::is_pod<A2>::value << ' ' << sizeof(B2) << std::endl; // 1 8
}
Run Code Online (Sandbox Code Playgroud)
现场演示// 使用 g++
人们通常说,当您从具有尾部填充的 POD 类型继承时,由于某些历史原因,Itanium ABI(老实说,我不知道那是什么)不允许重新使用基类的尾部填充子对象(如果该子对象是 POD)。
然而,在第三种情况下,A2是 POD,因为它的所有成员都具有相同的访问控制,但B2正在重用此类尾部填充。这是为什么?
当前标准始终允许在任何基类子对象中重用对齐尾孔。它不一定是“POD”(或现代的等价物,“简单可复制”)。事实上,任何基类子对象都是“潜在重叠子对象”,而“潜在重叠子对象”是不能够memcpy的。
Itanium ABI 不跟踪什么是或不是 POD 或当前标准中的等效项。它允许(实际上强制)在任何不是C++98 定义的POD 的基础子对象中重用对齐尾孔。
此 ABI 仅使用 POD 的定义来决定是否在基类子对象的尾部填充中分配对象。虽然这些标准随着时间的推移扩大了 POD 的定义,但它们也禁止程序员使用 memcpy 等直接读取或写入基类子对象的底层字节。因此,即使在最保守的解释中,实现也可以在任何类的尾部填充中自由分配对象,而这在 C++98 中不是 POD。此 ABI 符合这一点。
在 C++98 中,A2不会是 POD,因为它有私有成员。因此,GCC 根据 ABI 重用尾部填充,并符合当前标准或任何回到 C++98 的先前标准。
| 归档时间: |
|
| 查看次数: |
607 次 |
| 最近记录: |