Solving the C++ NULL Type Safety Problem

The problem

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.

The solution

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;
}

Complete Source Code

A complete sample program for null, together with a test suite, is available here.


Back to Martin's home page
Last modified: Mon Jan 27 01:43:06 PST 2003
Copyright © 2003 Martin Buchholz