在c++的早期,当它被固定在C的顶部时,你不能使用NULL,因为它被定义为(void*)0。你不能将NULL赋值给除void*以外的任何指针,这使得它有点无用。在那些日子里,人们接受使用0(零)作为空指针。

直到今天,我仍然使用0作为空指针,但我周围的人坚持使用null。我个人认为给一个现有的值命名(NULL)没有任何好处-因为我也喜欢将指针作为真值测试:

if (p && !q)
  do_something();

那么使用0就更有意义了(就像如果你使用NULL,你不能在逻辑上使用p && !q -你需要显式地与NULL进行比较,除非你假设NULL为零,在这种情况下为什么要使用NULL)。

是否有任何客观的原因让人们更喜欢0而不是NULL(反之亦然),或者这只是个人偏好?

编辑:我应该补充(最初的意思是说),对于RAII和异常,我很少使用零/NULL指针,但有时你仍然需要它们。


当前回答

我想说,历史已经证明了这一点,那些主张使用0(零)的人是错误的(包括Bjarne Stroustrup)。支持0的理由主要是审美和“个人偏好”。

c++ 11创建后,使用新的nullptr类型,一些编译器开始抱怨(使用默认形参)将0传递给带有指针参数的函数,因为0不是指针。

如果代码是使用NULL编写的,那么可以通过代码库执行简单的搜索和替换,使其成为nullptr。如果您被使用0作为指针编写的代码所困扰,那么更新它将变得更加乏味。

如果你现在必须为c++ 03标准编写新代码(并且不能使用nullptr),你真的应该只使用NULL。这将使您将来更容易更新。

其他回答

我尽量使用c++参考来避免整个问题。而不是

void foo(const Bar* pBar) { ... }

你可能经常会写作

void foo(const Bar& bar) { ... }

当然,这并不总是有效的;但是空指针可能会被过度使用。

我通常用0。我不喜欢宏,而且不能保证您使用的某些第三方头文件不会将NULL重新定义为一些奇怪的东西。

你可以使用一个由Scott Meyers和其他人提出的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 = {};

谷歌"nullptr"获取更多信息。

将指针设置为0并不那么清楚。特别是如果你使用c++以外的语言。这包括C语言和Javascript。

我最近用这样的代码删除:

DrawTo(BITMAP *buffer) =0;

第一次为纯虚函数。我以为这只是一个星期的魔术表演。当我意识到它基本上只是将函数指针设置为空(因为在c++的大多数情况下虚函数只是函数指针)时,我踢了自己一脚。

DrawTo(BITMAP *buffer) =null;

如果我的新眼睛没有间隔的话就不会那么令人困惑了。实际上,我想知道为什么c++不使用小写的null,就像它现在使用小写的false和true一样。

我很久以前就停止使用NULL而改用0了(以及大多数其他宏)。我这样做不仅是因为我想尽可能地避免宏,还因为NULL似乎在C和c++代码中被过度使用了。它似乎被用于任何需要0值的地方,而不仅仅是指针。

在新项目中,我把这个放在项目头中:

static const int nullptr = 0;

现在,当c++ 0x兼容的编译器到来时,我所要做的就是删除这一行。 这样做的一个好处是Visual Studio已经将nullptr识别为关键字并适当地突出显示它。

    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位来为你归零?我见过某些编译器(例如英特尔的icpc)不是那么友好——这导致了运行时错误。