C ++ + g cc: повторное использование хвостовой подкладки и POD - PullRequest
2 голосов
/ 01 мая 2020

Смежный вопрос: Стандартная компоновка и хвостовое заполнение

Фрагмент:

#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 // Использование g ++

Обычно говорят, что, когда вы наследуете от типа POD с дополнением хвоста, по некоторым историческим причинам, Itanium ABI (честно говоря, я не знаю, что это такое) не позволяет повторно использовать заполнение хвоста подобъект базового класса, если таким подобъектом является POD.

Однако в третьем случае A2 - это POD, поскольку все его члены имеют одинаковое управление доступом, но B2 повторно использует такую ​​оконечную прокладку. Это почему?

1 Ответ

2 голосов
/ 02 мая 2020

Текущий стандарт всегда позволяет повторно использовать хвостовые отверстия выравнивания в любом подобъекте базового класса. Это не обязательно должен быть «POD» (или современный эквивалент, «легко копируемый»). Действительно, любой подобъект базового класса является «потенциально перекрывающимся подобъектом», а «потенциально перекрывающиеся подобъекты» не memcpy -able.

Itanium ABI не отслеживает, что есть или нет POD или эквивалент в текущем стандарте. Это позволяет (на самом деле, обязывает) выравнивающие хвостовые отверстия повторно использовать в любом базовом подобъекте, который не является POD в соответствии с определением C ++ 98 .

1.1 Определения :

Этот ABI использует определение POD только для того, чтобы решить, следует ли размещать объекты в концевом заполнении подобъекта базового класса. Хотя стандарты со временем расширили определение POD, они также запретили программисту напрямую читать или записывать базовые байты подобъекта базового класса, скажем, с помощью memcpy. Следовательно, даже в самой консервативной интерпретации реализации могут свободно размещать объекты в дополнении хвоста любого класса, который не был бы POD в C ++ 98. Этот ABI соответствует этому.

В C ++ 98, A2 не был бы POD, потому что он имеет закрытых членов. Таким образом, G CC повторно использует хвостовую подкладку в соответствии с ABI и в соответствии с текущим стандартом или любым предыдущим стандартом до C ++ 98.

...