问题
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