是否安全#define NULL nullptr?
我在下面的macros中看到了许多最顶级的头文件:
#define NULL 0 // C++03
在所有的代码中, NULL
和0
可以互换使用。 如果我改变它。
#define NULL nullptr // C++11
会造成不良副作用吗? 我可以想到以下用法的唯一(好)副作用将会变形,
int i = NULL;
我在最顶层的头文件中看到了下面的macros:
您应该没有看到,标准库在<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*)
但是,如果是这样的话,反正几乎肯定是坏的。
更好的是在整个代码中用nullptr
search和replaceNULL
。
它可能在语法上是安全的,但是你会在哪里放置#define
? 它会产生代码组织问题。
不,你不能(重新)定义标准的macros。 如果你看到
#define NULL 0
在标准标题以外的任何文件的顶部(甚至在那里,它应该在包括守卫中,并且通常在附加的守卫中),那么该文件被破坏。 去掉它。
请注意,好的编译器通常会用类似下面的方式定义NULL
:
#define NULL __builtin_null
,要访问一个编译器内build函数,如果它在非指针上下文中使用,将会触发一个警告。
除非你编写自己的<cstddef>
版本,否则你不应该定义它。 它当然不应该在“许多最顶级的头文件”中。
如果你正在实现你自己的标准库,那么唯一的要求是
18.2 / 3macrosNULL是一个实现定义的C ++空指针常量
所以无论是0
还是nullptr
都是可以接受的,而nullptr
更好(如果你的编译器支持的话)。
也许不会
如果你有一个特定的重载行为格式:
void foo(int); void foo(char*);
那么代码的行为:
foo(NULL);
将根据NULL是否更改为nullptr而改变。
当然,还有另外一个问题,就是在这个答案中写出这样的代码是否安全?
虽然它可能会破坏旧版本的兼容性,但是对于较新的代码来说,这是一个没有问题的事情。 你应该使用nullptr
,而不是NULL
,你的意思是nullptr
。 此外,你应该使用0
,你的意思是零。