LINUX.ORG.RU

[c++]NULL и nullptr

 


0

1

В новом стандарте си+ обещают константу nullptr которая как NULL, но для указателей. Вот меня мучает вопрос: а NULL тогда для чего? Почему бы не отнять у NULL способность быть интом? Неужели есть какие-то люди, которые NULL используют не для инициализации/сравнения с указателями и у них всё прям сломается? Нахрена новое уродливое ключевое слово?

PS бинарное представление нулевого указателя в данном контексте не волнует и роли не играет.

★★★★★

>Неужели есть какие-то люди, которые NULL используют не для инициализации/сравнения с указателями

конечно есть

annulen ★★★★★
()

> Почему бы не отнять у NULL способность быть интом?

для совместимости с горой старого кода

aho
()
Ответ на: комментарий от legolegs

>0 не выглядит как указатель

лол, как будто NULL выглядит как указатель)

по стандарту 0 в С++ работает как надо, NULL - пережиток темных времен юности С

annulen ★★★★★
()

> Неужели есть какие-то люди, которые NULL используют не для инициализации/сравнения с указателями

Встречал и продолжаю встречать такое использование NULL. Чаще всего NULL передают функции, принимающей целочисленный аргумент, и такие ошибки не отлавливаются обычными компиляторами. nullptr должен помочь компилятору в таких случаях.

anonymous
()

> NULL тогда для чего

В плюсах NULL это просто макрос для 0, который рекомендовано использовать для обозначения нулевого указателя: «The macro NULL is implementation-defined C++ null pointer constant in this International Standard». При этом корректность семантики использования этого макроса компилятор не проверяет - эта задача целиком возложена на программиста.

anonymous
()

> Почему бы не отнять у NULL способность быть интом?

Хотя бы потому что использование макросов в С++ не приветствуется.

anonymous
()

сделали бы nil или NIL, теперь и без того уродливый язык станет ещё уродливее.

mashina ★★★★★
()
Ответ на: комментарий от anonymous

Ага вот уже похоже на ответ, спасибо.

Чаще всего NULL передают функции, принимающей целочисленный аргумент

Следующий вопрос: зачем? это же целое - целое - это 0. Это какая-то традиция? Секта? Или есть причины? Чтобы с O не перепутали что-ли?

legolegs ★★★★★
() автор топика
Ответ на: комментарий от aho

>> Почему бы не отнять у NULL способность быть интом?

для совместимости с горой старого кода

Я честно говоря не поручусь головой, что ввод кейворда nullptr ничего не сломает. И если, как тут сказали, NULL передаётся в функции вместо 0, то замена макроса NULL==0 на кейворд NULL==((void*)0) ничего не должна сломать.

legolegs ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Мне нравится писать int* foobar = NULL; Мне не хочется переучиваться и писать int* foobar = nullptr; только от того, что несколько доисторических сишников любили писать int hurr = NULL;

legolegs ★★★★★
() автор топика
Ответ на: комментарий от aho

Ну, мне собственно плевать. Я плюсы не знаю. Мне и С хватает (которых я тоже не знаю, но не знаю меньше, чем плюсы) :)

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от nocomer

[troll]А вообще один из авторов предложения Herb Sutter, так что все это происки майкрософт и попытки популяризовать C#[/troll]

nocomer
()
Ответ на: комментарий от nocomer

Ага, вот типа ответ:

The alternative name NULL is not available. NULL is already the name of an implementation-defined macro in the C and C++ standards. If we defined NULL to be a keyword, it would still be replaced by macros lurking in older code. Also, there might be code “out there” that (unwisely) depended on NULL being 0. Finally, identifiers in all caps are conventionally assumed to be macros, testable by #ifdef, etc.

son_I_am_disapoint.jpg

be replaced by macros lurking in older code - не аргумент. Это ничего не сломает. Плюсы новшевства это старому коду тоже не принесёт, но старый код и трогать не трогают.

Also, there might be code “out there” that (unwisely) depended on NULL being 0 - ах бедные говнокодеры, мы сломаем их говнокод. Чувствуется рука майкрософта.

finally, identifiers in all caps are conventionally assumed to be macros - Уж с NULL то никто не запутается, слишком он особенный. #ifdef NULL - это может быть артефактом какого-то совсем древнего кода, который заставляли работать в кривых несуществующих ныне компиляторах.

Вохражения надуманные, люди будут просто делать #define NULL nullptr, а зачем делать в стандарте недоделки - непонятно.

А ещё я нашёл совсем странные вещи:

An object of type nullptr_t ... cannot be converted to any other type including any integral or bool type

Они там о чём вообще думают? Указатель нельзя к булу привести, этож надо. if(ptr) как делать?

legolegs ★★★★★
() автор топика
Ответ на: комментарий от legolegs

> Они там о чём вообще думают? Указатель нельзя к булу привести, этож надо. if(ptr) как делать?

это nullptr нельзя к булу привести, а не указатель - nullptr_t это
decltype(nullptr)

aho
()

> PS бинарное представление нулевого указателя в данном контексте не волнует и роли не играет.

А меня как раз волнует именно это: какого хрена не прописали в стандартах бинарное представление NULL-a равным 0..

Ну и поддерживаю недоумение ТС по поводу нового ключевого слова (да ещё такого уродского).

gandjubas
()
Ответ на: комментарий от gandjubas

>какого хрена не прописали в стандартах бинарное представление NULL-a равным 0.

Да тут-то всё просто: железки бывают сильно разные

legolegs ★★★★★
() автор топика
Ответ на: комментарий от annulen

А еще есть такие люди, которые тащат в свои проги любую «фишку», в прочитанной на ночь книжке, просто потому, что могут так сделать. Очень умиляют в сорцах цитаты из Александрески и прочих гур. - с указанием выходных данных книжки, только что без ISBN...

slackwarrior ★★★★★
()

Новая константа в стандарте на хрен не нужна

ttnl ★★★★★
()
Ответ на: комментарий от legolegs

Сейчас даже самые убогие 8-мибитные чипы на С программируют, вполне могли бы зафиксировать требование по NULLу.

gandjubas
()
Ответ на: комментарий от Eddy_Em

NULL — это 0. А 0 — это форма записи нулевого указателя. Как при этом физически представлен нулевой указатель — никого волновать не должно.

geekless ★★
()
Ответ на: комментарий от Eddy_Em

> Не нравится писать 0 вместо NULL, можно сделать через одно место: (void *) 0

Стыд и срам! Если бы вы изволили ознакомиться с системой типов языка С++, то знали что неявного преобразования из void* в T* не существует. Т.о. после вашего предложения не скомпилируется даже простейшая конструкция: T* p = NULL;

anonymous
()
Ответ на: комментарий от Eddy_Em

> Ну, мне собственно плевать. Я плюсы не знаю. Мне и С хватает

Тогда понятно, почему вы предлагаете NULL определить как (void*)0. То что, работает в Си не обязательно работает в С++.

Но мне не понятно, почему вы не зная С++, даете по нему людям советы? Иногда лучше промолчать.

anonymous
()
Ответ на: комментарий от legolegs

> Следующий вопрос: зачем? это же целое - целое - это 0. Это какая-то традиция? Секта? Или есть причины? Чтобы с O не перепутали что-ли?

Причины у каждого свои: от традиции до банальной ошибки. В случае банальной ошибки большинство компиляторов даже варнинга не кинут, более того даже все тесты будут пройдены.

anonymous
()
Ответ на: комментарий от legolegs

> Я честно говоря не поручусь головой, что ввод кейворда nullptr ничего не сломает.

Тебе и не надо за это головой ручаться, ручаться за это будет комитет. А сломать всегда можно, например, если слово nullptr уже используется в программе в качестве идентификатора.

замена макроса NULL==0 на кейворд NULL==((void*)0) ничего не должна сломать

legolegs, Eddy_Em, рекомендую вам осилить хотя бы одну толковую книжечку по языку С++. Особенно уделите внимание разделу посвященному неявным преобразованиям типов.

anonymous
()
Ответ на: комментарий от legolegs

> несколько доисторических сишников любили писать int hurr = NULL;

нормальные сишники как раз так и не пишут, т.к. сишный компилятор вправе сделать #define NULL (void*)0, а это приведет как минимум к варнингу.

anonymous
()
Ответ на: комментарий от legolegs

> Мне нравится писать int* foobar = NULL; Мне не хочется переучиваться и писать int* foobar = nullptr;

Не хочешь не пиши - силом никто заставлять не будет.

anonymous
()
Ответ на: комментарий от Eddy_Em

> А переучиваться никто и не заставляет. Что, трудно сделать #define NULL 0?

Eddy_Em, ты наверное не поверишь, но в большинстве плюсовых компиляторов именно так и сделано.

anonymous
()
Ответ на: комментарий от legolegs

> ах бедные говнокодеры, мы сломаем их говнокод

Сынок, добро пожаловать в реальный мир! В мир где живут постоянно ошибающиеся люди! В мир где идеального кода нет!

anonymous
()
Ответ на: комментарий от gandjubas

> Сейчас даже самые убогие 8-мибитные чипы на С программируют, вполне могли бы зафиксировать требование по NULLу.

А ничего что на самых убогих 8-битных чипах можно/нужно писать и читать по нулевому адресу?

anonymous
()
Ответ на: комментарий от anonymous

Да, верно:

int * foo = ( (void*)0);
<stdin>:4:14: ошибка: некорректное преобразование из ‘void*’ в ‘int*’
Спасибо, что указали. Хотя под "((void*)0)" я имел ввиду ту хрень, которую собирваются обозвать nullptr.

legolegs ★★★★★
() автор топика
Ответ на: комментарий от anonymous

>>люди будут просто делать #define NULL nullptr

Зачем?

Потому что NULL заметнее. Сразу видно, что указатель занулён. А это важно. А nullptr можно спутать с каким-нибудь bullptr и долго отлаживать. Но фичи, которые даёт nullptr - нужны. Он во всём лучше NULL, кроме названия.

legolegs ★★★★★
() автор топика
Ответ на: комментарий от legolegs

А NULL можно спутать с HULL. Для этого существует подцветка кода.

Это из той же серии, что и отступы и скобки, звездочки у типов или переменных и тд.

JackyTreehorn
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.