首先要说的是:在代码库中,一致性(consistency)至关重要,比决策本身更重要。
在C++中
在C++中,NULL被定义为0
或0L
。
如果你读过《The C++ Programming Language》,Bjarne Stroustrup建议在赋值时显式使用0
以避免使用NULL
宏,但我不确定他在比较时是否也这样做。我已经有一段时间没有读这本书了,我认为他只是使用if(some_ptr)
而没有进行明确的比较,但我有点模糊。
这样做的原因是NULL
宏是欺骗性的(像几乎所有的宏一样),它实际上是一个0
字面量,而不是名称所暗示的唯一类型。避免使用宏是C++中的一般指导方针之一。另一方面,0
看起来像一个整数,但与指针进行比较时却不是整数。就我个人而言,我可以采取任何一种方式,但通常我跳过明确的比较(虽然有些人不喜欢这样做,这可能就是你有一个贡献者建议改变的原因)。
无论个人感受如何,这在很大程度上是选择最小恶的一种方式,因为没有一个正确的方法。
这是一个清晰且常见的习惯用法,我更喜欢它,因为在比较时没有意外赋值的风险,而且阅读起来很清晰:
if (some_ptr) {}
如果你知道some_ptr
是一个指针类型,那么这是很清楚的,但它也可能看起来像一个整数比较:
if (some_ptr != 0) {}
这是比较清晰的,通常情况下它是有意义的... 但这是一个不安全的抽象,NULL
实际上是0
字面量,可能很容易被误用:
if (some_ptr != NULL) {}
C++11现在有nullptr
,这是首选方法,因为它是明确且准确的,只需注意意外赋值:
if (some_ptr != nullptr) {}
在你能够迁移到C++0x之前,我认为担心使用哪种方法都是浪费时间,它们都不足以满足要求,这就是为什么nullptr被发明出来的原因(还有与完美转发相关的通用编程问题)。最重要的是保持一致性。
在C中
C是一个不同的东西。
在C中,NULL
可以定义为0
或((void*)0)
,而C99允许实现定义空指针常量。所以实际上取决于实现对NULL
的定义,你需要检查标准库。
宏非常常见,在一般情况下,它们经常用于弥补语言中通用编程支持的缺陷和其他东西。该语言更加简单,并且依赖预处理器更加普遍。
从这个角度来看,在C中我可能会推荐使用NULL
的宏定义。