Совместимые типы и строгие правила псевдонимов
Это общая стратегия в C, чтобы наложить один тип на другой тип, полагаясь на то, что макет структуры C имеет определенные гарантии. Библиотеки, такие как GLib, полагаются на это, чтобы реализовать объектно-ориентированное наследование. В основном:
struct Base
{
int x;
int y;
};
struct Derived
{
struct Base b;
int z;
};
Это позволяет привязать указатель Base*
к адресу объекта Derived
.
Но я также знаю правило < строгое псевдонижение", которое является неявным предположением компилятора о том, что разные типы указатели не могут указывать на один и тот же адрес. (Это позволяет компилятору выполнить определенные оптимизации.)
Итак, как эти две вещи примирились? Многие библиотеки C, включая Glib, CPython и т.д., Используют приведенную выше стратегию для различения типов. Все они просто компилируются с такими флагами, как no-strict-aliasing
?
Ответы
Ответ 1
В этом случае нет строгого сглаживания. struct Derived
содержит a struct Base
. Этот тип поведения явно разрешен стандартом языка. От C11 6.7.2.1 Спецификаторы структуры и объединения, пункт 15:
Указатель на объект структуры, соответствующим образом преобразованный, указывает на его исходный элемент (или если этот элемент является битовым полем, а затем в единицу, в которой он находится) и наоборот.