In C the null pointer macro NULL is generally defined like this:
#define NULL ((void *)0) /* C */
This gives us at least a warning when NULL is used in an integral context like
NULL + 1
In C++, the C definition doesn't work because
int *p = NULL;does not compile. For this reason, the C++ standard requires NULL to be a compile-time integral constant equal to zero.
#define NULL 0 /* C++ */This allows the above statement to compile successfully. Unfortunately, this sacrifices type safety, because NULL can also be used in a numeric context without generating a compile error.
Much ink has been spilled discussing NULL.
Let's analyze the problem a little deeper. We want NULL to have these properties:
By stating the problem in this way, the solution jumps out at you (at least if you've been working with templates). We simply make NULL an object that has templated conversion operators to any pointer type. The code writes itself.
namespace { struct { template <typename T> operator T* () const { return static_cast<T*> (0); } } null; }
That was too easy. So while we're here, we can also write a slightly more sophisticated null pointer to member.
namespace { struct { template <class T, typename U> operator U T::* () const { return static_cast<U T::*> (0); } } null_ptr_to_member; }
A complete sample program for null, together with a test suite, is available here.