Ответ на этот вопрос: это зависит от того, какой языковой стандарт вы используете: -).
В C90 и C ++ это недопустимо, потому что вы выполняете косвенное обращение к нулевому указателю (выполняя *p
), и это приводит к неопределенному поведению.
Однако в C99 этот является действительным, правильно сформированным и четко определенным. В C99, если операнд унарного - &
был получен в результате применения унарного - *
или путем выполнения подписки ([]
), то ни &
, ни *
, ни []
применены. Например:
int* p = 0;
int* q = &*p; // In C99, this is equivalent to int* q = p;
Аналогично,
int* p = 0;
int* q = &p[0]; // In C99, this is equivalent to int* q = p + 0;
Из С99 §6.5.3.2 / 3:
Если операнд [унарного оператора &
] является результатом унарного оператора *
, ни этот оператор, ни оператор &
не оцениваются, и результат такой, как если бы оба опущены, за исключением того, что ограничения на операторы все еще применяются, и результат не является lvalue.
Аналогично, если операнд является результатом оператора []
, ни оператор &
, ни унарный *
, подразумеваемый []
, не оцениваются, и результат выглядит так, как если бы &
оператор был удален, а оператор []
был заменен на оператор +
.
(и его сноска № 84):
Таким образом, &*E
эквивалентно E
(даже если E
- нулевой указатель)