C++ C+++;gcc:尾部填充重用和吊舱

C++ C+++;gcc:尾部填充重用和吊舱,c++,inheritance,padding,abi,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; ch

相关问题:

片段:

#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
}
#包括
#包括
结构A0
{
INTA;
字符c;
};
结构B0:A0
{char d;};
结构A1
{
INTA;
私人:
字符c;
};
结构B1:A1
{char d;};
结构A2
{
私人:
INTA;
字符c;
};
结构B2:A2
{char d;};
int main()
{

std::cout当前标准始终允许在任何基类子对象中重用对齐尾孔。它不必是“POD”(或现代等价物,“可复制的微不足道”)。事实上,任何基类子对象都是“潜在重叠的子对象”,并且“潜在重叠的子对象”不可
memcpy
-able

安腾ABI不跟踪当前标准中的POD或等效物。它允许(事实上是强制要求)在任何根据C++98定义不是POD的基本子对象中重用对齐尾孔

:

该ABI仅使用POD的定义来决定是否在基类子对象的尾部填充中分配对象。虽然标准随着时间的推移扩展了POD的定义,但它们也禁止程序员使用memcpy直接读取或写入基类子对象的底层字节。因此,ev在最保守的解释中,实现可以在C++98中没有POD的任何类的尾部填充中自由分配对象


在C++98中,
A2
不会是POD,因为它有私有成员。因此,GCC根据ABI重用尾部填充,并遵循当前标准或任何以前的标准返回到C++98。

没有从POD继承的特殊规则(或本周的术语)在C++标准中,也不在ItAuthAbi类中,可以重用其潜在重叠的子对象中的空洞(其中<代码> B2::A2是),除非类本身是一个POD(< <代码> B2< /代码>)。“@n.”代词m。这就是我所指的:您链接的问题表明填充可以重用。为什么您认为它不能重用?“@n.”代词m。可以在类基子对象为非POD时重用,但是,在我的第三种情况下,子对象为POD,填充已经重用。那么,这里的真正限制是什么?尽管我认为您当您说类本身(不是基类,而是派生类)时,已经回答了我的问题请注意,在C++ 20中删除<代码> iSpod OD/CUT>,考虑使用<代码> ISStAtdialdSudio可以提供标准中的任何引用来支持你的第一句话吗?这适用于任何孔还是只尾尾?@ M。如果你搜索的话,这个答案似乎有一些相关的引文。“潜在重叠子对象”你会找到所有内容。我认为这适用于所有孔,但安腾ABI只重用尾孔(但不要引用我的话)。这个问题涉及到新的位置(结束子对象的生存期似乎与修改它的某些字节不同)由于同一问题,您无法将可能重叠的子对象或memcpy重用到可能重叠的子对象。其内存中可能有属于其他对象的内容,您可能会对其进行重击。链接答案中的引号仅适用于“在对象的生命周期结束之后,在对象占用的存储被重用或释放之前,“这不是为额外对象使用“活动”尾部填充的情况