Dereference null не всегда UB?

Я всегда знал, что Стандарт предусматривает разыменование null - UB. Однако

(ссылка 1) говорит

p = 0; *п; по своей сути не является ошибкой.

и предоставляет ссылку на

(ссылка 2) говорит

* p не является ошибкой, когда p равно null, если значение lvalue не преобразуется в lvalue

(Я считаю, что опечатка и, вероятно, должна читать значение lvalue преобразуется в rvalue)

Ссылка 1 также говорит

char * p = 0; char * q = & * (p)

"не undefined", который я мог бы читать только как четко определенный или, по крайней мере, определенный реализацией

Может ли адвокат языка дать авторитетное объяснение того, что происходит?

Ответ 1

Я исследовал тему косвенности с помощью нулевых указателей в этом ответе. Короче говоря, он действительно четко определен как таковой, как это было разработано в ваших цитированных основных проблемах. Комитет использовал понятие пустой ценности, предложенное много лет назад (но никогда не принятое); *p должен быть таким пустым значением lvalue, и если мы не попытаемся получить доступ к (несуществующей) ячейке памяти за этим значением lvalue (например, путем преобразования lvalue-to-rvalue), все остальные операции ведут себя так, как ожидалось, Например. &*p эквивалентно p, если p недействителен. (Это также работает для указателей в конце массива, что необходимо для общей идиомы &arr[n]).

Я также начал писать бумагу для пустых lvalues ​​ (это WIP, а rebase против N4640 еще не завершена), поэтому есть шанс, что мы увидим больше этого на более позднем этапе.