Presenting the Problem
In C++, the macro
NULL is a synonym for the literal 0. For this reason, most C++ programs use 0 directly to
initialize, assign, and compare null pointers. Whether you're using
NULL or 0, your C++ apps are subjected to bugs and maintenance problems that are caused by the ambiguity of 0. Consider these two overloaded versions of a function called
func:
void func(int);
void func (char *);
int main()
{
func(0); //which func is called?
}
The function call
func(0) is always resolved as
func(int), never as
func(char *)even if you meant to call the latter with a null pointer argument! To call the latter, you must use an explicit cast expression:
func( (char *)0); //ugly but unavoidable
Most C++ programmers aren't aware of this trap; they mistakenly assume that passing
NULL as the argument of
func will invoke the
char* overload:
func(NULL); //still calls func(int)
Remember: In C++,
NULL is a synonym for the literal 0. It's never implemented as
void* because
NULL must also be compatible with
pointers to members:
struct A {/**/};
int (A::*pmf)(char *)=NULL;
However, there is a subtler problem involving
NULL and 0. When you modify a large corpus of code automatically (by using search and replace or a script), it's very difficult to distinguish between code statements in which 0 stands for a numeric value and statements that use 0 as a null pointer. Using
NULL is only a partial solution because
NULL is replaced with the literal 0 during the preprocessing stage. Furthermore, you have to
#include a standard header file in order to use
NULL. What you want is a strongly-typed, built-in keyword whose meaning is unambiguous and explicit. This is exactly what
nullptr is.