Строгое правило алиасинга определено где-то еще.Это формулировка:
C (ИСО / МЭК 9899: 1999 6.5 / 7):
Объект должен иметь свое сохраненное значение, доступный только через выражение lvalue, которое имеет одно изследующие типы:
- тип, совместимый с действующим типом объекта,
- квалифицированная версия типа, совместимого с эффективным типом объекта,
- тип, который является типом со знаком или без знака, соответствующим действующему типу объекта,
- тип, который является типом со знаком или без знака, соответствующим квалифицированной версии действующего типа объекта,
- агрегатный или объединенный тип, который включает в себя один из вышеупомянутых типов среди своих членов (включая, рекурсивно, член субагрегированного или автономного объединения), или
- тип символа.
C ++ (ISO / IEC 14882: 2011 3.10 [basicl.lval] / 15):
Если программа пытается получить доступ к сохраненному значению объекта через lvalue другогочем одиндля следующих типов поведение не определено:
- динамический тип объекта,
- cv-квалифицированная версия динамического типа объекта,
- тип, подобный (как определено в 4.4) динамическому типу объекта,
- тип, который является типом со знаком или без знака, соответствующий динамическому типу объекта,
- тип, которыйявляется типом со знаком или без знака, соответствующим квалифицированной для cv версии динамического типа объекта,
- агрегатного или объединенного типа, который включает в себя один из вышеупомянутых типов среди своих элементов или нестатических элементов данных (включая, рекурсивно, элемент или нестатический член данных субагрегата или содержащего объединения),
- тип, который является (возможно, cv-квалифицированным) типом базового класса динамического типа объекта,
- a
char
или unsigned char
типа.
Стандарт C не запрещает вам приводить указатель к несвязанному типу, если нетпроблемы с выравниванием.Однако из-за строгого правила псевдонимов вы не можете разыменовать указатель, полученный из такого приведения.Поэтому единственное полезное, что можно сделать с таким «недопустимым» указателем, - привести его обратно к правильному типу (или совместимому типу).
Это в основном то же самое в C ++ с reinterpret_cast (5.2.10 [expr.reinterpret.cast] / 7):
Указатель объекта может быть явно преобразован в указатель объектадругой тип.Когда значение v
типа «указатель на T1
» преобразуется в тип «указатель на cv T2
», результатом будет static_cast<cv T2*>(static_cast<cv void*>(v))
, если оба T1
и T2
являются типами стандартной компоновки (3.9), и требования к выравниванию T2
не являются более строгими, чем требования T1
, или если любой тип равен void
.Преобразование значения типа «указатель на T1
» в тип «указатель на T2
» (где T1
и T2
являются типами объектов и где требования по выравниванию T2
не являются более строгими, чем требования T1
) и возврат к исходному типу возвращает исходное значение указателя.Результат любого другого такого преобразования указателя не определен.