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

What is the difference between NULL and __null in C++?

我有以下代码:

MyType x = NULL;

NetBeans 给了我一个建议,将其更改为:

MyType x = __null;

我查了一下,发现 __null 被称为 "compiler keyword",我认为这意味着它在编译器内部使用。我不明白为什么 NetBeans 建议将其更改为编译器关键字。

c++中的NULL__null有什么区别?

__null 是一个 g++ 内部事物,其作用与 C++11 中添加的标准 nullptr 大致相同(始终充当指针,从不作为整数) .

NULL定义为0,可以隐式用作整数、布尔值、浮点值或指针,这在重载解析时是个问题,当你想调用专门接受指针的函数。

无论如何,您不应该使用 __null,因为它是一个 g++ 实现细节,因此使用它保证不可移植的代码。如果您可以依赖 C++11(现在肯定可以了吗?),请使用 nullptr。如果没有,NULL 是您唯一的便携式选择。

NULL 是空指针的旧 C 符号。 C++ 传统上使用 0 作为空指针,并且自从 C++11 标准 nullptr.

考虑到 x 似乎不是指针那么你不能将 x 初始化为空指针,而 __null 符号可能是一些编译器- null value 的内部符号(这是一个在标准 C++ 中并不真正存在的概念)。

如果你想x初始化为一些默认状态,那么你必须依赖MyClass默认构造函数来将对象及其成员变量初始化为一些合适的默认值。

NULL 已从 C 取代为 C++,并且在 C++11 之前采用了其 C 含义:

until C++11: The macro NULL is an implementation-defined null pointer constant, which may be an integral constant expression rvalue of integer type that evaluates to zero.

C++11 随后引入了类型为 std::nullptr_t 的专用空指针文字 nullptr。但是 - 可能是为了向后兼容 - 宏 NULL 没有被删除;它的定义有点宽松,因为编译器现在可以将它定义为整型或指针类型:

C++11 onwards: an integer literal with value zero, or a prvalue of type std::nullptr_t

如果您使用 NULL,那么您将在重载决策中获得实现定义的行为。例如,考虑以下代码以及使用 NULL-macro 的整数版本的编译器。然后使用 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,相比之下,非常便携。