Является ли Оптимизация Пустого Базового Класса теперь обязательной оптимизацией (по крайней мере для классов стандартной компоновки)?
В соответствии с C++ 11 9.1 / 7 (черновик n3376) класс стандартной компоновки - это класс, который:
не имеет нестатических членов-данных типа нестандартного класса макета (или массива таких типов) или ссылки,
не имеет виртуальных функций (10.3) и виртуальных базовых классов (10.1),
имеет одинаковый контроль доступа (пункт 11) для всех нестатических элементов данных,
не имеет базовых классов нестандартной компоновки,
либо не имеет нестатических членов данных в самом производном классе и не более одного базового класса с нестатическими членами данных, или не имеет базовых классов с нестатическими членами данных, и
не имеет базовых классов того же типа, что и первый нестатический член данных.
из этого следует, что пустой класс является классом стандартной компоновки; и что другой класс с пустым классом в качестве базы также является классом стандартной компоновки при условии, что первый нестатический член данных такого класса не имеет тот же тип, что и база.
Кроме того, 9.2 / 19 гласит, что:
Указатель на объект структуры стандартной компоновки, соответствующим образом преобразованный с использованием
reinterpret_cast
, указывает на свой начальный элемент (или, если этот элемент является битовым полем, то на модуль, в котором он находится), и наоборот. [Примечание: Следовательно, в объекте структуры стандартной компоновки может быть безымянный отступ, но не в его начале, что необходимо для достижения соответствующего выравнивания. —Конечная записка]
Кажется, это подразумевает, что Оптимизация Пустого Базового Класса теперь является обязательной оптимизацией, по крайней мере для классов стандартной компоновки. Я хочу сказать, что если бы оптимизация пустой базы не была обязательной, то компоновка класса стандартного макета не была бы стандартной, а скорее зависела бы от того, реализует ли реализация упомянутую оптимизацию или нет. Верны ли мои рассуждения или я что-то упустил?
1 ответ
Да, вы правы, это было указано в предложениях "Пересмотрено POD": http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2007/n2342.htm
Документы компилятора Embarcadero также указывают это: http://docwiki.embarcadero.com/RADStudio/en/Is_standard_layout
Другой ключевой момент - [class.mem]/16
Два типа структуры стандартного макета (раздел 9) совместимы с макетом, если они имеют одинаковое количество элементов не статических данных, а соответствующие элементы нестатических данных (в порядке объявления) имеют типы, совместимые с макетом (3.9).
Обратите внимание, что только элементы данных влияют на совместимость макетов, а не базовые классы, поэтому эти два стандартных класса макетов совместимы с макетом:
struct empty { };
struct stdlayout1 : empty { int i; };
struct stdlayout2 { int j; };