C++ + gcc:尾部填充重用和 POD [英] C++ + gcc: tail padding reuse and PODs

查看:98
本文介绍了C++ + gcc:尾部填充重用和 POD的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相关问题:标准布局和尾部填充

片段:

#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
}

现场演示//使用 g++

人们通常说,当您从具有尾部填充的 POD 类型继承时,由于某些历史原因,Itanium ABI(老实说,我不知道那是什么)不允许重新使用尾部填充如果子对象是 POD,则为基类子对象.

It's usually said that, when you inherit from a POD type with tail padding, for some historical reasons, the Itanium ABI (that honestly, I don't know what that is) doesn't allow to reause tail padding of a base-class subobject if such subobject is POD.

然而,在第三种情况下,A2 是 POD,因为它的所有成员都具有相同的访问控制,但是 B2 正在重用这种尾部填充.这是为什么?

However, in the third case, A2 is POD because all of its members have the same access control, but B2 is reusing such tail padding. Why is that?

推荐答案

当前标准始终允许在任何基类子对象中重用对齐尾孔.它不必是POD"(或现代等效物,可简单复制").实际上,任何基类子对象都是潜在重叠子对象",而潜在重叠子对象"不是 memcpy-able.

The current standard always allows alignment tail holes to be reused in any base class subobject. It doesn't have to be a "POD" (or a modern-day equivalent, "trivially copyable"). Indeed, any base class subobject is a "potentially-overlapping subobject", and "potentially-overlapping subobjects" are not memcpy-able.

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

The Itanium ABI doesn't keep track of what is or is not a POD or equivalent in the current standard. It allows (mandates, in fact) alignment tail holes to be reused in any base subobject which is not a POD according to the C++98 definition.

1.1 定义:

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

This ABI uses the definition of POD only to decide whether to allocate objects in the tail-padding of a base-class subobject. While the standards have broadened the definition of POD over time, they have also forbidden the programmer from directly reading or writing the underlying bytes of a base-class subobject with, say, memcpy. Therefore, even in the most conservative interpretation, implementations may freely allocate objects in the tail padding of any class which would not have been POD in C++98. This ABI is in compliance with that.

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

In C++98, A2 would not have been a POD because it has private members. So GCC reuses the tail padding according to the ABI, and in compliance with the current standard or any previous standard back to C++98.

这篇关于C++ + gcc:尾部填充重用和 POD的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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