Стандартная компоновка c++

Я просматривал отличные статьи на C++ POD, тривиальные и стандартные классы компоновки Одно свойство, которое я не понял о стандартной компоновке, заключается в следующем: -

 A standard layout has no base classes of the same type as the first 
    non-static data member

таким образом, следующее не будет стандартным макетом, поскольку он имеет первый член, такой же, как базовый класс

struct NonStandardLayout3 : StandardLayout1 {
    StandardLayout1 x; // first member cannot be of the same type as base
};

но с точки зрения производительности и свойств, как вышеуказанная структура отличается от

struct StandardLayout5 : StandardLayout1 {
    int x;
    StandardLayout1 y; // can have members of base type if they're not the first   
};

- коррекции выше этот.

1 ответов


причина в том, что типы стандартной компоновки эффективно санкционируют "пустую оптимизацию базового класса", где базовые классы без членов данных не занимают места и имеют тот же адрес, что и первый член данных (если таковой имеется) производного класса.

однако попытка сделать это, когда базовый класс имеет тот же тип, что и первый элемент данных, нарушает модель памяти C++, которая требует, чтобы различные объекты того же типа должны иметь разные адреса.

от ISO / IEC 14882: 2011 1.8 [вступление.объектом]/6:

два объекта, которые не являются битовыми полями, могут иметь один и тот же адрес, если один из них является подобъектом другого, или если по крайней мере один является субобъектом базового класса нулевого размера и они имеют разные типы; в противном случае они должны иметь разные адреса

эффективно санкционирование пустого базового класса, 9.2 [class.mem] / 20:

указатель на объект структуры стандартного макета, соответствующим образом преобразованный с помощью reinterpret_cast, указывает на его начальный элемент (или если этот элемент является битовым полем, то к единице, в которой он находится) и наоборот.

это было бы невозможно для следующих типов (Type1 и Type2) быть совместимыми с макетом (хотя в противном случае они были бы классами стандартной компоновки) без этого ограничения.

struct S1 {};
struct S2 {};

struct Type1 : S1 {
    S1 s;
    int k;
};

struct Type2 : S1 {
    S2 s;
    int m;
};