А>по C NULL машинно зависим т.е. может и не быть в представлении машины нулем,
А>а Страуструп пишет что можно безболезненно менять 0 на NULL. Что делать?

Ты путаешь понятие "физического нуля" с понятием "логического нуля".

Есть понятие null-pointer constant. И есть понятие null-pointer value of type 'T*'. Это совершенно разные вещи.

Null-pointer value of type 'T*' — это "физический ноль", это конкретное физическое значение null-указателя данного типа 'T*' на данной платформе. Это то значение, которое физически ложится в указатель, когда ты на уровне С/С++ кода присваиваешь этому указателю литеральный 0. Это может быть и '0x00000000', и '0x12345678', и '0xBAADF00D'. Это значение в общем случае зависит от платформы. Более того, оно даже может зависеть от конкретного типа 'T*'.

Null-pointer constant — это "логический ноль", это некотрое значение уровня языка С/С++, которое будучи приведено к указательному типу превращается в null-pointer value этого указательного типа. В языках С/С++ любое целочисленное константное выражение со значением 0 (включая просто литеральный '0') явлется null-pointer value, по определению. На любой платформе, в любой реализации. Поэтому если литеральный '0' привести к типу указателя, то всегда получится null-pointer value этого указательного типа (который, как уже было сказано выше, физически зависит от платформы).

NULL — это именно null-pointer constant. Он не "машинно зависим", как ты неверно предположил выше. NULL в роли null-pointer constant всегда строго эквивалентен просто '0'. На любой платформе, в любой реализации.

Другими словами, если в некоторой реализации на некоторой платформе null-pointer value типа 'void*' представляется физическим значением 0x12345678, то вот такой С/С++ код

void* p1 = 0;
void* p2 = NULL;


будет транслироваться этой реализацией в машинный код, заносящий значение 0x12345678 в указатели 'p1' и 'p2'.

Как видишь, нет никакого конфликта между '0'/'NULL' и физическим значением null-pointer value на данной платформе.
Автор: Андрей Тарасевич    Оценить