#define NULL nullptr是否安全?

时间:2012-01-25 13:22:36

标签: c++ null c++11 nullptr

我在许多最顶层的头文件中看到了下面的宏:

#define NULL 0  // C++03

在所有代码中,NULL0可互换使用。如果我改成它。

#define NULL nullptr  // C++11

会不会引起任何不良副作用?我可以想到唯一(好的)副作用,因为以下用法会变得格格不入;

int i = NULL;

6 个答案:

答案 0 :(得分:40)

  

我在最顶层的头文件中看到了下面的宏:

您不应该看到,标准库在<cstddef>(和<stddef.h>)中定义它。而且,IIRC,根据标准,重新定义标准头文件定义的名称会导致未定义的行为。所以从纯粹的标准来看,你不应该这样做。


我见过人们做了以下事情,无论出于何种原因,他们心碎的想法:

struct X{
  virtual void f() = NULL;
}

(如[错误]:“将虚拟表格指针设置为NULL”)

仅当NULL定义为0时才有效,因为= 0是纯虚函数的有效标记(§9.2 [class.mem])。

那就是说,如果NULL 正确用作空指针常量,那么什么都不应该破坏。

但是,请注意,即使看似正确使用,也会发生变化:

void f(int){}
void f(char*){}

f(0); // calls f(int)
f(nullptr); // calls f(char*)

然而,如果情况确实如此,那几乎肯定会被打破。

答案 1 :(得分:14)

更好的方法是在整个代码中使用NULL搜索并替换nullptr

它可能在语法上是安全的,但你会把#define放在哪里?它会产生代码组织问题。

答案 2 :(得分:7)

没有。您不允许(重新)定义标准宏。如果你看到

#define NULL 0

在标准标题以外的任何文件的顶部(甚至在那里,它 应该包括警卫,并且通常在其他警卫中 好吧),那个文件坏了。删除它。

请注意,优秀的编译器通常会定义NULL 像:

#define NULL __builtin_null

,访问内置编译器,如果是,则触发警告 在非指针上下文中使用。

答案 3 :(得分:4)

你根本不应该定义它,除非你正在编写自己的<cstddef>版本;它肯定不应该在“许多最顶级的头文件”中。

如果您要实现自己的标准库,那么唯一的要求是

  

18.2 / 3宏NULL是一个实现定义的C ++空指针常量

因此,0nullptr是可以接受的,nullptr更好(如果您的编译器支持它),原因是您提供的。

答案 4 :(得分:4)

可能不是

如果您有特定格式的重载行为:

void foo(int);
void foo(char*);

然后是代码的行为:

foo(NULL);

将根据NULL是否更改为nullptr而改变。

当然,还有一个问题是,编写此答案时是否可以安全地使用此代码...

答案 5 :(得分:2)

虽然它可能会破坏向后兼容旧版本的内容(要么是过于聪明......),对于较新的代码,这不是问题。您应该使用nullptr,而不是NULL,您的意思是nullptr。此外,您应该使用0表示零。