Строгий псевдоним - это c или c ++? - PullRequest
6 голосов
/ 03 сентября 2011

В ISO / IEC 9899: TC2 стандарт гласит следующее

6.3.2.3 Указатели

  1. Указатель на объект или неполный тип может быть преобразован в указатель на другой объект или неполный тип. Если результирующий указатель не выровнен правильно для указательного типа, поведение не определено. В противном случае при обратном преобразовании результат сравнивается равным исходному указателю. Когда указатель на объект преобразуется в указатель на символьный тип, результат указывает на младший адресуемый байт предмет. Последовательные приращения результата, вплоть до размера объекта, дают указатели на оставшиеся байты объекта.

Итак, из стандарта не ясно, может ли указатель одного типа быть приведен к указателю другого типа.

1 Ответ

14 голосов
/ 03 сентября 2011

Строгое правило алиасинга определено где-то еще.Это формулировка:

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) и возврат к исходному типу возвращает исходное значение указателя.Результат любого другого такого преобразования указателя не определен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...