在C++中,NULL和__null有什么区别?

37
我有以下代码:
MyType x = NULL;

NetBeans给了我一个建议,将它更改为这样:

MyType x = __null;

我查了一下,发现__null被称为"编译器关键字",我猜它是在编译器内部使用的。我不明白为什么NetBeans建议把它改成编译器关键字。

c++中NULL__null有什么区别?


48
在C++11及以后的版本中,你应该使用关键字nullptr。 - Anon Mail
7
不要使用__null。如果它是一个实现细节,使用它是不可移植的。如果它被项目定义,那么使用这个名称是保留给实现使用的,使用这个标识符是不合法的,并且应该将其从项目中删除。 - François Andrieux
3
如果你想使用“NULL”,请使用“nullptr”。如果这无法编译,那么你可能没有指针,正在执行错误的操作。 - NathanOliver
你总是想要使用 nullptr - Jesper Juhl
1
NetBeans 提出的建议有些奇怪。也许值得向开发人员反映,尽管由于提供的信息不足,我们无法确定。 - Lightness Races in Orbit
3个回答

56

__nullg++的一个内部机制,作用类似于C++11中添加的标准nullptr(始终作为指针而不是整数)。

NULL被定义为0,可以隐式地用作整数、布尔值、浮点值或指针,这在重载解析时会出现问题,当您想要调用特定接受指针的函数时。

总之,您不应该使用__null,因为它是g++的实现细节,因此使用它会导致非可移植代码。如果您可以依赖于C++11(现在肯定可以了吧?),请使用nullptr。否则,NULL是您唯一可移植的选项。


17
请注意,“NULL”不一定被定义为“0”。它取决于实现者选择的空指针常量。 - Pete Becker
1
@PeteBecker:没错。只是在C++11之前,我不知道有哪些系统没有使用0。在C++11时代,它们可以使其评估为nullptr,但我不确定是否有任何编译器已经触发了这个特定的开关(因为它可能会破坏现有的代码)。 - ShadowRanger
2
@PeteBecker 我认为这里存在一些混淆,即指针地址中的 0 和源代码中的字面量 0。后者被定义为在分配给指针时产生空指针,即使结果地址是实现定义的。 - David Conrad
1
@ShadowRanger NULL 有时被定义为 0,有时被定义为 (void *) 0,这取决于编译器。 - David Conrad
5
@DavidConrad - 在C中,(void*)0是一个有效的空指针常量,但在C++中不是 - Pete Becker
显示剩余2条评论

12

NULL已经从C语言被引入到了C++,并且在C++11之前采用了其在C语言中的含义:

在C++11之前:宏NULL是一个实现定义的空指针常量,可以是一个求值为零的整数类型的积分常数表达式右值。

C++11引入了一个专门的空指针字面值nullptr,类型为std::nullptr_t。但是,出于向后兼容的考虑,宏NULL没有被删除,它的定义只是有点放松,编译器现在可以将其定义为整型或指针类型:

C++11及以后版本:值为零的整数字面量,或类型为std::nullptr_t的prvalue

如果使用NULL,则在重载决议中会得到实现定义的行为。例如,考虑以下代码与使用整数版本的NULL宏的编译器。然后,将NULL作为参数传递给函数的调用可能会导致模棱两可:

struct SomeOverload {

    SomeOverload(int x) {
        cout << "taking int param: " << x << endl;
    }
    SomeOverload(void* x) {
        cout << "taking void* param: " << x << endl;
    }
};

int main() {

    int someVal = 10;

    SomeOverload a(0);
    SomeOverload b(&someVal);

    // SomeOverload c(NULL);  // Call to constructor is ambiuous
    SomeOverload d(nullptr);
}

建议在表达指针类型时使用 nullptr

不要使用 __null,因为它是特定于编译器的、不可移植的常量;相比之下,nullptr 是完全可移植的。


8

NULL是旧的C语言中表示空指针的符号。C++传统上使用0来表示空指针,自从C++11标准以后则使用nullptr

考虑到x似乎不是一个指针,因此您不能将x初始化为空指针,而__null符号也许是一些编译器内部用来表示空值的符号(这在标准C++中并不存在的概念)。

如果您想要将x初始化为某个默认状态,则必须依赖于MyClass的默认构造函数来初始化对象及其成员变量为适当的默认值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接