TL; DR
С учетом следующего кода:
int* ptr;
*ptr = 0;
делает *ptr
требуется преобразование значения lvalue-r-значение ptr
перед применением косвенности?
Стандарт охватывает тему lvalue-to-rvalue во многих местах, но, похоже, не указывает достаточно информации, чтобы определить, требует ли оператор * такого преобразования.
Подробнее
Преобразование lvalue-to-rval покрывается в N3485 в разделе 4.1
Преобразование 1-го значения в значение 1 и 1 говорит (акцент мой идет вперед):
Значение gl (3.10) нефункционного типа без массива T может быть преобразовано к prvalue.53 Если T - неполный тип, программа, которая требует, чтобы это преобразование плохо сформировалось. Если объект, которому glvalue не является объектом типа T и не является объектом тип, полученный из T, или если объект не инициализирован, программа что требует такого преобразования undefined поведение. [...]
Значит, *ptr = 0;
требует этого преобразования?
Если мы перейдем к пункту 1 раздела 4
, он говорит:
[...] Стандартная последовательность преобразования будет применена к выражению при необходимости, чтобы преобразовать его в требуемый тип адресата.
Итак, когда это необходимо? Если мы рассмотрим раздел 5
Выражения, преобразование lvalue-to-rvalue упоминается в пункте 9, в котором говорится:
Всякий раз, когда выражение glvalue появляется как операнд оператора который ожидает prvalue для этого операнда, lvalue-to-rvalue (4.1), стандарт "массив-к-указателю" (4.2) или стандартная функция-указатель (4.3) конверсии применяются для преобразования выражения в prvalue. [...]
и параграф 11, в котором говорится:
В некоторых контекстах выражение появляется только для его побочных эффектов. Такое выражение называется выражением отбрасываемого значения. [...] Преобразование lvalue-to-rvalue (4.1) применяется тогда и только тогда, когда выражение является lvalue волатильно-квалифицированного типа и является одним из следующие [...]
ни один из абзацев не применим к этому образцу кода и 5.3.1
Унарные операторы, указанные в пункте 1, говорят:
Унарный * оператор выполняет косвенное направление: выражение, которому оно применяется указатель на тип объекта или указатель на тип функции, и результатом является lvalue, относящееся к объекту или функции, к которой относится выражение. Если тип выражения является "указателем на T", тип результата - "T". [Примечание: косвенность через указатель на неполный тип (кроме cv void). Полученное таким образом lval может использоваться ограниченным образом (для инициализации ссылка, например); это значение не должно быть преобразовано в prvalue, см. 4.1. -end note]
похоже, не требуется значение указателя, и я не вижу никаких требований к преобразованию указателя здесь, я что-то упускаю?
Почему нам все равно?
Я видел ответ и комментарии в других вопросах, в которых утверждается, что использование неинициализированного указателя - это поведение undefined из-за необходимости преобразования lvalue-to-rval ptr
перед применением косвенности. Например: Где, на самом деле, стандарт С++ говорит о разыменовании неинициализированного указателя, это undefined поведение? делает этот аргумент, и я не могу примирить аргумент с тем, что выложено в любом из последних проектов вариантов стандарта. Поскольку я видел это несколько раз, я хотел получить разъяснения.
Фактическое доказательство поведения undefined не так важно, поскольку, как я заметил в связанном вопросе выше, мы имеем другой способ добраться до поведения undefined.