MyType x = NULL;
NetBeans给了我一个建议,将它更改为这样:
MyType x = __null;
我查了一下,发现__null
被称为"编译器关键字",我猜它是在编译器内部使用的。我不明白为什么NetBeans建议把它改成编译器关键字。
c++中NULL
和__null
有什么区别?
__null
是g++
的一个内部机制,作用类似于C++11中添加的标准nullptr
(始终作为指针而不是整数)。
NULL
被定义为0
,可以隐式地用作整数、布尔值、浮点值或指针,这在重载解析时会出现问题,当您想要调用特定接受指针的函数时。
总之,您不应该使用__null
,因为它是g++
的实现细节,因此使用它会导致非可移植代码。如果您可以依赖于C++11(现在肯定可以了吧?),请使用nullptr
。否则,NULL
是您唯一可移植的选项。
0
。在C++11时代,它们可以使其评估为nullptr
,但我不确定是否有任何编译器已经触发了这个特定的开关(因为它可能会破坏现有的代码)。 - ShadowRanger0
和源代码中的字面量 0
。后者被定义为在分配给指针时产生空指针,即使结果地址是实现定义的。 - David ConradNULL
有时被定义为 0
,有时被定义为 (void *) 0
,这取决于编译器。 - David Conrad(void*)0
是一个有效的空指针常量,但在C++中不是。 - Pete BeckerNULL
已经从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
是完全可移植的。
NULL
是旧的C语言中表示空指针的符号。C++传统上使用0
来表示空指针,自从C++11标准以后则使用nullptr
。
考虑到x
似乎不是一个指针,因此您不能将x
初始化为空指针,而__null
符号也许是一些编译器内部用来表示空值的符号(这在标准C++中并不存在的概念)。
如果您想要将x
初始化为某个默认状态,则必须依赖于MyClass
的默认构造函数来初始化对象及其成员变量为适当的默认值。
__null
。如果它是一个实现细节,使用它是不可移植的。如果它被项目定义,那么使用这个名称是保留给实现使用的,使用这个标识符是不合法的,并且应该将其从项目中删除。 - François Andrieuxnullptr
。 - Jesper Juhl