Здравствуйте, Аноним, Вы писали:
А>по C NULL машинно зависим т.е. может и не быть в представлении машины нулем, А>а Страуструп пишет что можно безболезненно менять 0 на NULL. Что делать?
Ниего не делать Конвертация из 0 в машинное представление нулевого указателя осуществляеться на основе типа константы
(int)0 всегда останется нулём (по умолчанию все числовые константы имеют тип int, если не указано другое)
(int *)0 будет преобразовано в машинное представление нулевого указателя.
Обычно преобразование типа параметра не шаблонной функции осуществляется на основе её прототипа. так что в
memcmp(0,0,0)
Первые 2 параметра это указатели, а третий(последний) это число.
К тому же вроде как
#define NULL 0
а не
#define NULL ((void *)0)
Так что NULL это просто более удобное и понятное в конкретном контексте название.
Здравствуйте, Аноним, Вы писали:
А>по C NULL машинно зависим т.е. может и не быть в представлении машины нулем, А>а Страуструп пишет что можно безболезненно менять 0 на NULL. Что делать?
Я всегда использовал 0. Это короче писать, да и NULL определен как 0 в C++. Но что-то мне кажется, что Страуструп подставил нас своей рекомендацией использовать 0, и вот почему: есть предложение ввести nullptr в язык. Соответственно, NULL будет определен как nullptr, а 0 так и останется 0. Следовательно, пользователи NULL получат эту новую фичу автоматически в отличии от тех, кто предпочитает писать 0.
Здравствуйте, alexkro, Вы писали:
a> NULL будет определен как nullptr, а 0 так и останется 0. Следовательно, пользователи a> NULL получат эту новую фичу автоматически в отличии от тех, кто предпочитает писать 0.
И те и другие, скорее всего, начнут писать nullptr вместо NULL/0. Так что разницы в новом
коде не будет. А старый и без того правильный
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Аноним, Вы писали:
А>по C NULL машинно зависим т.е. может и не быть в представлении машины нулем, А>а Страуструп пишет что можно безболезненно менять 0 на NULL. Что делать?
Строго говоря, разницы нет.
Но я вот что скажу: я всегда писАл NULL хотя бы из-за того, что в любой момент могу по всему своему коду сделать даже не #define, а хоть find&replace NULL на 0, а вот наоборот не получится... Ну и еще как-то понятней выглядит, например, какой параметр передается в функцию — указатель, или число.
Другое дело, что было бы неплохо, если бы этому еще имелась поддержка со стороны компилятора — тот же nullptr, как тут уже говорили.
Здравствуйте, Аноним, Вы писали:
А>по C NULL машинно зависим т.е. может и не быть в представлении машины нулем, А>а Страуструп пишет что можно безболезненно менять 0 на NULL. Что делать?
Нет.
Нулевой указатель внутренне может быть представлен как угодно (что там пишется в регистры), но на уровне языка Си (и С++ тоже) он равен числу 0.
(То есть так его воспримут операторы ==, !=, а также конверсия в булевский тип).
Оператор reinterpret_cast, естественно, дает доступ к внутреннему представлению указателя.
Поэтому на экзотических архитектурах можно получить приколы
reinterpret_cast<long>((void*)0) != (long)0
Не будем забывать, что указатели (особенно на члены класса) устроены сложнее, чем просто целое число — смещение в плоском адресном пространстве. Поэтому выполнять reinterpret_cast можно с оглядкой на архитектуру.
А>по 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 на данной платформе.