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
,相比之下,非常便携。
我有以下代码:
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
,相比之下,非常便携。