Стандартная компоновка 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;
};