В первые дни C++, когда он был привязан к C, вы не могли использовать NULL, поскольку он был определен как (void*)0. Вы не могли присвоить NULL ни одному указателю, кроме void*, что делало его бесполезным. В те дни было принято, что вы используете 0 (ноль) для нулевых указателей.
По сей день я продолжаю использовать ноль в качестве нулевого указателя, но окружающие настаивают на использовании NULL. Я лично не вижу никакой пользы в присвоении имени (NULL) существующему значению - и поскольку мне также нравится проверять указатели как значения истинности:
if (p && !q)
do_something();
тогда использование нуля имеет больше смысла (например, если вы используете NULL, вы не можете логически использовать p && !q - вам нужно явно сравнить с NULL, если вы не предполагаете, что NULL равен нулю, и в этом случае зачем использовать NULL).
Есть ли объективная причина предпочитать ноль перед NULL (или наоборот), или все это просто личные предпочтения?
Обновлено: я должен добавить (и изначально хотел сказать), что с RAII и исключениями я редко использую указатели нуля / NULL, но иногда они вам все еще нужны.





Вот мнение Страуструпа по этому поводу: Часто задаваемые вопросы о стилях и методах C++
In C++, the definition of
NULLis 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem withNULLis that people sometimes mistakenly believe that it is different from 0 and/or not an integer. In pre-standard code,NULLwas/is sometimes defined to something unsuitable and therefore had/has to be avoided. That's less common these days.If you have to name the null pointer, call it
nullptr; that's what it's called in C++11. Then,nullptrwill be a keyword.
Тем не менее, не переживайте по мелочам.
Бьярн написал это до того, как C++ 0x начал работать над новым нулевым типом. Будет так, что NULL будет использоваться для этого типа, когда он доступен для платформы, и я думаю, вы увидите изменение C в общем консенсусе по этому поводу.
Я думаю, что стандарт гарантирует, что NULL == 0, поэтому вы можете сделать то же самое. Я предпочитаю NULL, потому что он документирует ваше намерение.
Если у вас есть вложенные структуры, я думаю, что foo.bar_ptr = (Bar *) 0 выражает намерение намного яснее, чем foo.bar_ptr = NULL. Эта привычка также дает возможность компилятору выявлять за вас ошибки, связанные с неправильным представлением. Для меня foo.bar_ptr = 0 выражает намерение, а также использует NULL, если я знаю, что foo.bar_ptr является указателем.
Однажды я работал на машине, где 0 был допустимым адресом, а NULL был определен как специальное восьмеричное значение. На этой машине (0! = NULL), поэтому такой код, как
char *p;
...
if (p) { ... }
не будет работать так, как вы ожидаете. Вы ДОЛЖНЫ написать
if (p != NULL) { ... }
Хотя я считаю, что в наши дни большинство компиляторов определяют NULL как 0, я все еще помню урок тех лет назад: NULL не обязательно равен 0.
Вы не использовали совместимый компилятор. Стандарт говорит NULL является 0 и что компилятор должен преобразовать 0 в контексте указателя в правильное истинное значение NULL для арки.
Да, ты прав. Это было в середине 80-х годов, прежде чем ANSI выпустил стандарт C. Тогда не существовало такой вещи, как соблюдение требований, и разработчики компиляторов могли свободно интерпретировать язык по своему усмотрению. Вот почему был необходим стандарт.
@EvanTeran Это неверно для C. (void *)0 должен быть сравнить равные to NULL, но на самом деле это не обязательно должно быть 0. Некоторые люди утверждали, что NULL должен быть 0xffffffff... или 0xf7ffffff..., поскольку 0x00 может быть допустимым адресом, но до сих пор в большинстве реализаций используется NULL = 0.
@yyny вы ошибаетесь. Есть разница между «нулевой константой» и «нулевым значением». Нулевая константа - ПО ОПРЕДЕЛЕНИЮ, 0 в соответствии со стандартом, это то, что вы пишете в своем коде. Однако компилятор может выбрать выдачу другого ЗНАЧЕНИЯ для нулевой константы в результирующем машинном коде. Другими словами, когда вы пишете p = 0; (где p - указатель), компилятор будет рассматривать 0 как нулевую константу. Но при выдаче инструкции для сохранения «null» будет сохранено зависящее от машины нулевое значение, которое может быть, а может и не быть буквально адресом 0x0.
Если я правильно помню, NULL определяется по-другому в заголовках, которые я использовал. Для C он определяется как (void *) 0, а для C++ - просто 0. Код выглядел примерно так:
#ifndef __cplusplus
#define NULL (void*)0
#else
#define NULL 0
#endif
Лично я все еще использую значение NULL для представления нулевых указателей, это явно указывает на то, что вы используете указатель, а не какой-то интегральный тип. Да, внутренне значение NULL по-прежнему равно 0, но оно не представлено как таковое.
Кроме того, я не полагаюсь на автоматическое преобразование целых чисел в логические значения, а сравниваю их явно.
Например, предпочитаю использовать:
if (pointer_value != NULL || integer_value == 0)
скорее, чем:
if (pointer_value || !integer_value)
Достаточно сказать, что все это исправлено в C++ 11, где можно просто использовать nullptr вместо NULL, а также nullptr_t, который является типом nullptr.
Я со Страуструпом в этом вопросе :-) Поскольку NULL не является частью языка, я предпочитаю использовать 0.
В основном личные предпочтения, хотя можно привести аргумент, что NULL делает совершенно очевидным, что объект является указателем, который в настоящее время ни на что не указывает, например
void *ptr = &something;
/* lots o' code */
ptr = NULL; // more obvious that it's a pointer and not being used
IIRC, стандарт не требует, чтобы NULL был равен 0, поэтому использование того, что определено в <stddef.h>, вероятно, лучше всего для вашего компилятора.
Другой аспект аргумента заключается в том, следует ли использовать логические сравнения (неявное приведение к типу bool) или явную проверку на NULL, но это также сводится к удобочитаемости.
Я всегда использую 0. Не по какой-то действительно продуманной причине, просто потому, что, когда я впервые изучал C++, я читал кое-что, что рекомендовало использовать 0, и я всегда делал это таким образом. Теоретически может возникнуть путаница в удобочитаемости, но на практике я ни разу не сталкивался с такой проблемой в тысячах человеко-часов и миллионах строк кода. Как говорит Страуструп, это просто личная эстетическая проблема, пока стандарт не станет nullptr.
Я предпочитаю использовать NULL, поскольку это дает понять, что ваше намерение - это значение, представляющее указатель, а не арифметическое значение. Тот факт, что это макрос, прискорбен, но поскольку он так широко укоренился, опасность невелика (если только кто-то не сделает что-то действительно тупоголовое). Я бы хотел, чтобы это было ключевое слово с самого начала, но что вы можете сделать?
Тем не менее, у меня нет проблем с использованием указателей как значений истинности самих по себе. Как и NULL, это укоренившаяся идиома.
C++ 09 добавит конструкцию nullptr, которая, на мой взгляд, давно назрела.
Я давно перестал использовать NULL в пользу 0 (как и большинство других макросов). Я сделал это не только потому, что хотел максимально избегать макросов, но и потому, что NULL, похоже, стал чрезмерно использоваться в коде C и C++. Кажется, он используется всякий раз, когда требуется значение 0, а не только для указателей.
В новых проектах я помещаю это в заголовок проекта:
static const int nullptr = 0;
Теперь, когда появятся компиляторы, совместимые с C++ 0x, все, что мне нужно сделать, это удалить эту строку. Приятным преимуществом этого является то, что Visual Studio уже распознает nullptr как ключевое слово и соответствующим образом выделяет его.
Использование NULL будет более переносимым в долгосрочной перспективе. 'nullptr' будет доступен для одних платформ и недоступен для других. Ваше решение здесь требует, чтобы вы использовали препроцессор вокруг своего объявления, чтобы гарантировать, что он присутствует только тогда, когда это необходимо. NULL сделает это автоматически.
Я не согласен. В краткосрочной перспективе он будет менее переносимым, пока компиляторы не догонят его. В долгосрочной перспективе он будет таким же портативным и, возможно, немного более читаемым.
Кроме того, вы всегда можете #define nullptr NULL для вашего компилятора, отличного от C++ 0x.
Я согласен с тем, что NULL используется слишком часто, я видел, как он использовался для обозначения нулевого символа терминатора в строке! Я не думаю, что это оправдывает полное избегание этого.
Используйте NULL. NULL показывает ваше намерение. То, что это 0, - это деталь реализации, которая не имеет значения.
0 не является деталью реализации. Стандарт определяет 0 как любой битовый шаблон, представляющий нулевой указатель.
Будто ..!! Чувак, C++ - это язык низкого уровня! Используйте 0, это хорошо известная идиома.
Я так понимаю, это часть стандарта. Что касается чтения кода, это деталь реализации. Читатель должен думать «NULL-указатель», а не «0, который в данном случае означает NULL-указатель, а не число, с которым я мог бы производить арифметические операции».
+1. Согласился с Энди. @Ferruccio, реализация деталь идеи программиста не то же самое, что реализация компилятора определенный
если вы используете NULL в простом коде без сложного заголовка, вы обнаружите ошибку «NULL не определен в этой области».
если «NULL не определен в этой области», то просто #include <stddef.h>
Я всегда использую:
NULL для указателей'\0' для символов0.0 для поплавков и парныхгде 0 подойдет. Это вопрос намерения сигнализировать. Тем не менее, я не анал об этом.
ya, вероятно, следует использовать 0.0F для чисел с плавающей запятой, чтобы избежать неявного преобразования типов
Есть несколько аргументов (один из которых относительно недавний), которые, как мне кажется, противоречат позиции Бьярна по этому поводу.
Документация о намерениях
Использование NULL позволяет выполнять поиск по его использованию, а также подчеркивает, что разработчик разыскивается использует указатель NULL, независимо от того, интерпретируется ли он компилятором как NULL или нет.
Перегрузка указателя и int относительно редко
Пример, который все цитируют:
void foo(int*);
void foo (int);
void bar() {
foo (NULL); // Calls 'foo(int)'
}
Однако, по крайней мере, на мой взгляд, проблема с вышеизложенным не в том, что мы используем NULL для константы нулевого указателя, а в том, что у нас есть перегрузки foo(), которые принимают очень разные типы аргументов. Параметр также должен быть int, так как любой другой тип приведет к неоднозначному вызову и, таким образом, сгенерирует полезное предупреждение компилятора.
Инструменты анализа могут помочь СЕГОДНЯ!
Даже в отсутствие C++ 0x сегодня доступны инструменты, которые проверяют, что NULL используется для указателей, а 0 используется для целочисленных типов.
C++ 11 будет иметь новый тип std::nullptr_t.
Это новейший аргумент в таблице. Проблема 0 и NULL активно решается для C++ 0x, и вы можете гарантировать, что для каждой реализации, которая предоставляет NULL, первое, что они сделают, это:
#define NULL nullptr
Для тех, кто использует NULL, а не 0, это изменение будет улучшением безопасности типов с минимальными усилиями или без них - во всяком случае, оно может также выявить несколько ошибок там, где они использовали NULL для 0. Для тех, кто использует 0 сегодня ... ну, надеюсь, они хорошо знают регулярные выражения ...
Я должен признать, что это довольно хорошие моменты. Я рад, что C++ 0x будет иметь нулевой тип, я думаю, что это сделает многое чище.
Хорошее резюме. Небольшая придирка - новый null будет ключевым словом 'nullptr' и / или новым типом 'std :: nullptr_t'
@ Ричард, почему бы не сделать наоборот? Вы можете использовать Meyers nullptr_t, а затем, когда 0x станет доступным, вы удалите #include и полностью сохраните его в безопасности.
@fnieto: Хорошее замечание. Такой подход имеет преимущество в безопасности и для C++ '98 / '03.
#define NULL nullptr кажется опасным. Хорошо это или плохо, но большая часть унаследованного кода использует NULL для других вещей, кроме 0. Например, дескрипторы часто реализуются как некоторый интегральный тип, и установка для них NULL не редкость. Я даже видел злоупотребления, такие как использование NULL для установки char на нулевой терминатор.
@AdrianMcCarthy: Я бы сказал, что это было опасно, если бы существовала опасность того, что код будет компилироваться незаметно и будет иметь другое значение. Я почти уверен, что это не так, поэтому на самом деле все неправильное использование NULL будет обнаружено.
@RichardCorden: Гм, это предполагает, что другие способы использования NULL на самом деле неверны. Многие API-интерфейсы уже давно используют NULL с ручками, и это фактически документированное использование со многими из них. Не прагматично внезапно ломать их и заявлять, что они делают что-то неправильно.
@AdrianMcCarthy: Это не черно-белое. Если вы используете такой API, вам придется быстро изменить NULl обратно на 0. Если вы не используете такой API, вы можете воспользоваться местами, где используется боркен, и исправить их.
Обычно я использую 0. Мне не нравятся макросы, и нет никакой гарантии, что какой-то сторонний заголовок, который вы используете, не переопределяет NULL, чтобы он стал чем-то необычным.
Вы можете использовать объект nullptr, предложенный Скоттом Мейерсом и другими, пока C++ не получит ключевое слово nullptr:
const // It is a const object...
class nullptr_t
{
public:
template<class T>
operator T*() const // convertible to any type of null non-member pointer...
{ return 0; }
template<class C, class T>
operator T C::*() const // or any type of null member pointer...
{ return 0; }
private:
void operator&() const; // Can't take address of nullptr
} nullptr = {};
Google "nullptr" для получения дополнительной информации.
Любая сторонняя библиотека, которая определяет NULL для чего-либо, кроме 0 (или (void*)0, если компилируется как код C), просто вызывает проблемы и не должна использоваться.
Вы когда-нибудь видели библиотеку, которая переопределяет NULL? Всегда? Если бы такая библиотека когда-либо существовала, у вас были бы большие проблемы, чем с переопределенным NULL, например, вы используете библиотеку, которая достаточно глупа, чтобы переопределить NULL.
Более десяти лет назад я смутно помню, что имел дело с некоторыми сторонними заголовками, возможно, Orbix или ObjectStore, которые действительно определяли NULL. Я думаю, что испытываю патологическую ненависть к макросам после того, как потратил несколько дней и ночей на попытки заставить различные сторонние заголовки работать с windows.h.
«Не люблю макросы» - это странная критика объектно-подобного #define. Может быть, вы хотите сказать, что вам не нравится препроцессор C?
@Andrew - Мне кажется, единственное преимущество NULL перед (type *)0 - это возможность поиска. В противном случае это кажется ненужным запутыванием, если бы это не была идиома C. Я лично считаю, что идиома распространения NULL повсюду заслуживает смерти. На мой взгляд, NULL - бесполезный макрос. Бритве Оккама здесь надо поработать ...
Переопределение стандартных макросов - неопределенное поведение iirc.
NULL - это стандартный макрос, и его не следует переопределять в какой-либо сторонней библиотеке.
Я стараюсь избежать ответа на этот вопрос, используя ссылки на C++, где это возможно. Скорее, чем
void foo(const Bar* pBar) { ... }
вы часто можете написать
void foo(const Bar& bar) { ... }
Конечно, это не всегда работает; но нулевыми указателями можно злоупотреблять.
Кто-то сказал мне однажды ... Я собираюсь переопределить NULL на 69. С тех пор я не использую его: P
Это делает ваш код довольно уязвимым.
Редактировать:
Не все в стандарте идеально. Макрос NULL - это константа нулевого указателя C++, определяемая реализацией, не полностью совместимая с макросом C NULL, который, помимо неявного скрытия типа, преобразует его в бесполезный и подверженный ошибкам инструмент.
NULL действует не как нулевой указатель, а как литерал O / OL.
Скажите, что следующий пример не сбивает с толку:
void foo(char *);
void foo(int);
foo(NULL); // calls int version instead of pointer version!
Из-за всего этого в новом стандарте появляется std :: nullptr_t
Если вы не хотите ждать выхода нового стандарта и хотите использовать nullptr, используйте хотя бы достойный, например, предложенный Мейерсом (см. Комментарий jon.h).
NULL - это четко определенная часть стандарта C++. Позволяя людям, которые любят переопределять стандартные макросы, редактировать код в вашем проекте, делает ваш код «уязвимым»; использование NULL - нет.
Странно, никто, в том числе Страуструп, не упомянул об этом. Говоря много о стандартах и эстетике, никто не заметил, что это опасный для использования 0 вместо NULL, например, в списке переменных аргументов в архитектуре, где sizeof(int) != sizeof(void*). Как и Stroustroup, я предпочитаю 0 по эстетическим соображениям, но нужно быть осторожным, чтобы не использовать его там, где его тип может быть неоднозначным.
И в этих опасных местах вы все равно можете использовать 0 при условии, что вы укажете, какой 0 вы имеете в виду - например, (int *)0, (char *)0, (const char *)0, (void *)0 или (unsigned long long) 0 или что-то еще. На мой взгляд, это выражает намерение намного яснее, чем NULL.
Конечно, если вы не знаете, что означает NULL.
Мне лично немного неприятно, чтобы напрасно приводил что-то к (void *), когда я мог использовать точный тип. Я специально привел пример (обычно) 64-битного целого числа в списке, потому что он аналогичен случаю указателя. Более того, если мое воспоминание о том, что старый C++ определил NULL как 0, верно (прошло много лет с тех пор, как я программировал на C++), то мы не наблюдаем улучшения в правильности программы. К счастью, новый стандарт C++ предоставляет ключевое слово nullptr, так что мы можем избавиться от этого уродства NULL и всей полемики при написании нового C++.
Вот почему приведение к (void*) было перенесено на NULL. И NULL на самом деле большую часть времени действительно выражает намерение довольно четко. И я думаю, что ваше воспоминание неверно. Не уверен в стандартах, но на практике я считаю, что это (void*)0. И да, nullptr - хороший инструмент для украшения, хотя он представляет собой то же самое, что и NULL - указание нулевого указателя без указания типа.
Цитата из Часто задаваемые вопросы Страуструпа: «В C++ определение NULL - 0, поэтому разница только эстетическая». См. Принятый верхний ответ Мартина Коута. Я не знаю, изменилось ли что-то с момента появления стандарта C++ 11 и его реализаций (ключевое слово nullptr). Таким образом, использование NULL в некоторых местах (списки переменных аргументов), даже если он, по вашему мнению, выражает намерение, может на некоторых / многих платформах просто создать совершенно неправильный код, которого вы пытались избежать, и запутать программиста C, который отлаживает ваш код C++ В самом деле .
C++ 11 nullptr является ключевое слово и намного надежнее, чем NULL, который является макрос. Использование nullptr - когда он доступен - должно более широко приводить к исправлению кода на разных платформах, тогда как NULL может привести к неожиданностям.
@FooF, на некоторых платформах - возможно. В моей реальности это сработало, и поэтому я подозреваю, что это было определено как указатель. Что касается надежности, да, то, что я пытался сказать, что использование nullptr несет то же сообщение, что и NULL, касается только выражения намерения, о котором вы упомянули в самом начале. (Предварительная обработка NULL на современном gcc дает __null, что бы это ни было).
По правде говоря, я удивлен, что в часто задаваемых вопросах Страуструпа до сих пор - после появления сообществ компиляторов C++ 11 и C++ и поставщиков, пришедших к выводу, что это нецелесообразно, - говорится, что макрос NULL определяется как 0. Что касается личного вкуса, я считаю, что макрос NULL - бесполезный реликт / идиома - почти так же нелепо, как определение макросов для (short) 0, (unsigned long long) 0, '\0' и так далее (особенно когда у нас уже есть 0L, 0.0f, 0.0 и т. д., Определенные базовым языком) .
@FooF, когда дело касается личного вкуса, я не люблю заглавные буквы;)
cerr << sizeof(0) << endl;
cerr << sizeof(NULL) << endl;
cerr << sizeof(void*) << endl;
============
On a 64-bit gcc RHEL platform you get:
4
8
8
================
Мораль истории. Вы должны использовать NULL, когда имеете дело с указателями.
1) Он объявляет ваше намерение (не заставляйте меня перебирать весь ваш код, пытаясь выяснить, является ли переменная указателем или каким-то числовым типом).
2) В некоторых вызовах API, ожидающих переменных аргументов, они будут использовать NULL-указатель, чтобы указать конец списка аргументов. В этом случае использование «0» вместо NULL может вызвать проблемы. На 64-битной платформе вызову va_arg требуется 64-битный указатель, но вы будете передавать только 32-битное целое число. Мне кажется, что вы полагаетесь на то, что остальные 32 бита будут обнулены для вас? Я видел некоторые компиляторы (например, Intel icpc), которые не так хороши, и это приводило к ошибкам во время выполнения.
NULL возможно не портативный, и небезопасный. Могут быть платформы, которые все еще #define NULL 0 (согласно Часто задаваемые вопросы Страуструпа: что мне использовать: NULL или 0?, цитируемому в верхнем вопросе, и это один из первых результатов поиска). По крайней мере, в более старом C++ 0 имеет особое концептуальное значение в контексте указателя. Не стоит думать конкретно о битах. Также обратите внимание, что в разных целочисленных контекстах (short, int, long long) «sizeof(0)» будет отличаться. Я думаю, что этот ответ немного ошибочен.
(Лично, как программист C в повседневной жизни, я пришел посетить этот вопрос, чтобы понять, почему люди хотят использовать NULL вместо (char *)0, (const char *)0 или (struct Boo *)0 или (void *)0 или что-то еще, чтобы выразить намерение более четко - не будучи (на мой взгляд) слишком громоздкий.)
Проголосуйте. это происходит в компиляторе msvc2013 C. в 64-битном режиме 0 при преобразовании в указатель не гарантирует, что указатель будет NULL.
NULL четко определен в стандарте, поэтому он абсолютно переносим. но использование NULL более понятно, и после обновления до C++ 11 вы можете легко искать и заменять NULL на nullptr, но для 0 как вы можете это сделать?
Установить указатель на 0 не так-то просто. Особенно, если вы используете язык, отличный от C++. Это включает C, а также Javascript.
Недавно я использовал такой код:
virtual void DrawTo(BITMAP *buffer) =0;
для чистой виртуальной функции впервые. Я думал, что это какой-то волшебный джиберджаш на неделю. Когда я понял, что это просто установка указателя функции на null (поскольку виртуальные функции в большинстве случаев являются просто указателями на функции для C++), я ударил себя.
virtual void DrawTo(BITMAP *buffer) =null;
был бы менее запутанным, чем эта разбойница без должного расстояния для моих новых глаз. На самом деле, мне интересно, почему C++ не использует null в нижнем регистре так же, как сейчас он использует нижний регистр false и true.
В общем, для указателей я предпочитаю NULl 0. Однако '= 0;' - это идиоматический способ объявить чистую виртуальную функцию в C++. Я настоятельно рекомендую вам не использовать '= NULL;' для этого конкретного случая.
Это самый забавный комментарий к StackOverflow. Вы, наверное, уже знаете, что приведенный вами пример является синтаксисом чистой виртуальной функции, а не указателем. И да, @danio прав, вы не должны использовать NULL для чистой виртуальной функции.
Использование 0 или NULL будет иметь тот же эффект.
Однако это не означает, что они оба являются хорошими практиками программирования. Учитывая, что нет никакой разницы в производительности, выбор варианта с низким уровнем осведомленности вместо агностической / абстрактной альтернативы является плохой практикой программирования. Помогите читателям вашего кода понять ваш мыслительный процесс.
NULL, 0, 0.0, '\ 0', 0x00 и whatelse все переводятся в одно и то же, но являются разными логическими объектами в вашей программе. Их следует использовать как таковые. NULL - это указатель, 0 - количество, 0x0 - значение, биты которого интересны и т. д. Вы не стали бы назначать '\ 0' указателю, компилируется он или нет.
Я знаю, что некоторые сообщества поощряют демонстрацию глубоких знаний об окружающей среде, нарушая условия окружающей среды. Однако ответственные программисты создают поддерживаемый код и не допускают подобных действий в свой код.
Ну, я выступаю за то, чтобы вообще не использовать указатели 0 или NULL, когда это возможно.
Их использование рано или поздно приведет к ошибкам сегментации в вашем коде. По моему опыту, это, и указатели в gereral - один из самых больших источников ошибок в C++.
кроме того, это приводит к появлению операторов if-not-null по всему вашему коду. Намного лучше, если вы всегда можете положиться на действительное состояние.
Почти всегда есть лучшая альтернатива.
Гарантированная ошибка сегментации (а это является, гарантированное в современных системах при разыменовании 0) - это полезный для отладки. Намного лучше, чем разыменовать случайный мусор и получить неизвестный результат.
Я бы сказал, что история заговорила, и те, кто выступал за использование 0 (ноль), были неправы (включая Бьярна Страуструпа). Аргументами в пользу 0 были в основном эстетика и «личные предпочтения».
После создания C++ 11 с его новым типом nullptr некоторые компиляторы начали жаловаться (с параметрами по умолчанию) на передачу 0 функциям с аргументами указателя, поскольку 0 не является указателем.
Если бы код был написан с использованием NULL, можно было бы выполнить простой поиск и замену в кодовой базе, чтобы вместо этого сделать его nullptr. Если вы застряли в коде, написанном с использованием 0 в качестве указателя, обновить его гораздо утомительнее.
И если вам нужно прямо сейчас написать новый код для стандарта C++ 03 (и вы не можете использовать nullptr), вам действительно стоит просто использовать NULL. Это упростит вам обновление в будущем.
Бьярн Страуструп предпочитает использовать 0 только потому, что ему не нравятся макросы, но также не хочет вводить новое ключевое слово. история доказывает, что он был неправ.
подождите, разве не требуется нулевой указатель для оценки как ложь, независимо от того, равен ли null внутренне или нет?