我在许多最顶层的头文件中看到了下面的宏:
#define NULL 0 // C++03
在所有代码中,NULL
和0
可互换使用。如果我改成它。
#define NULL nullptr // C++11
会不会引起任何不良副作用?我可以想到唯一(好的)副作用,因为以下用法会变得格格不入;
int i = NULL;
答案 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 ++空指针常量
因此,0
或nullptr
是可以接受的,nullptr
更好(如果您的编译器支持它),原因是您提供的。
答案 4 :(得分:4)
可能不是
如果您有特定格式的重载行为:
void foo(int);
void foo(char*);
然后是代码的行为:
foo(NULL);
将根据NULL是否更改为nullptr而改变。
当然,还有一个问题是,编写此答案时是否可以安全地使用此代码...
答案 5 :(得分:2)
虽然它可能会破坏向后兼容旧版本的内容(要么是过于聪明......),对于较新的代码,这不是问题。您应该使用nullptr
,而不是NULL
,您的意思是nullptr
。此外,您应该使用0
表示零。