Это можно рассматривать как расширение для этого вопроса (меня интересует только C, но добавление С++ для завершения расширения)
В стандарте C11 в пункте 6.3.2.3.3 говорится:
Целочисленное константное выражение со значением 0 или выражением, выражаемым типом
void *, называется константой нулевого указателя.
То, что я считаю лично, это то, что 0 и (void *)0 представляют нулевой указатель, чье целочисленное значение может не быть 0, но это не распространяется на 0, отличное от любого другого типа.
Но стандарт продолжает:
Если константа нулевого указателя преобразуется в тип указателя, результирующий указатель, называемый нулевым указателем,...
который покрывает (int *)0 как нулевой указатель, поскольку cast - это явное преобразование (C11, 6.3), которое указано в методах преобразования.
Однако меня удивляет следующая фраза
... или такое выражение, которое применяется к типу
void *...
С этой семантикой эта фраза кажется совершенно бесполезной. Вопрос в том, является ли эта фраза совершенно бесполезной? Если нет, какие последствия у него есть? Следовательно, есть (int *)0 нулевой указатель или нет?
Другой вопрос, который может помочь в обсуждении, следующий. Рассматривается ли (long long)123 "123 преобразован в long long" или "123 с типом long long". Другими словами, есть ли какое-либо преобразование в (long long)123? Если их нет, то вторая цитата не охватывает (int *)0 как нулевой указатель.