C++ + gcc: tail padding reuse and PODs

元气小坏坏 提交于 2021-01-27 17:44:34

问题


Related question: Standard-layout and tail padding

Snippet:

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

Live demo // Using g++

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.

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?


回答1:


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.

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 Definitions:

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.

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.



来源:https://stackoverflow.com/questions/61548135/c-gcc-tail-padding-reuse-and-pods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!