Ответ 1
Это не убирает предварительный процесс, &*
просто заканчивается эквивалентом самого указателя, мы можем это увидеть, перейдя в проект стандарта C99 6.5.3.2
Операторы адреса и косвенности, указанные в пункте 4, в котором говорится:
Унарный * оператор обозначает косвенность. Если операнд указывает на функцию, результат обозначение функции; если он указывает на объект, результатом является значение l, обозначающее объект. Если операнд имеет тип '' указатель на тип, результат имеет тип ''. Если недопустимое значение было присвоено указателю, поведение унарного * оператора undefined. 87)
и в сноске 87 говорится:
Таким образом, & * E эквивалентно E (даже если E является нулевым указателем), [...]
и в пункте 3 говорится (внимание мое):
Унарный и оператор дает адрес своего операнда. Если операнд имеет тип типа '', результат имеет тип '' указатель на тип. Если операнд является результатом унарного * оператора, ни тот оператор, ни оператор и не оцениваются, и результат выглядит так, как если бы оба были omitted, за исключением того, что ограничения на операторы все еще применяются, и результат не является значением l.
Обновить
Возможно, стоит отметить, что для gcc
и clang
вы можете просмотреть результаты предварительной обработки, используя флаг -E
(см. его в прямом эфире) и в Visual Studio fooobar.com/questions/34399/... (посмотреть в прямом эфире).
Кроме того, стоит отметить, что, как сказал MSalters в своем комментарии, просто наличие двух токенов &*
недостаточно для понимания контекста, как показывает его пример:
int *p, *q ;
int foo = *p & *q ;
Таким образом, просто удаление &*
даже не было бы возможным на этапе предварительной обработки, поскольку у вас не было бы достаточной информации, чтобы определить, был ли &
адресом оператора или побитового оператора.