C++ Tutorial: Enhance Type Safety and Code Clarity with the nullptr Keyword

Introduction

The literal 0 has a unique position in C++ programming -- it automatically converts to almost every fundamental type, depending on the context:

  int x=0;
  double d=0;
  char * pstr=0; //null pointer
  int (A::*pmf)(int) =0; //null pointer to member
  bool flag=0; //Boolean false

Using 0 as a null pointer might lead to overload resolution bugs such as this:

  void f(int); //#1
  void f(char *);//#2
  
  f(0); //which f is called?

The C++ programmer believes that #2 is called. However, the compiler interprets 0 in this context as an integer, never as a pointer, and selects #1 instead. Things get worse when the macro NULL is used. Recall that NULL in C++ programming is merely a synonym for 0:

  f(NULL); //calls f(int)!

C usually defines NULL as (void*)(0). Many compilers don't even issue a warning in this case. The bug is detected (if ever) only at crash-time.

In contemporary C++ programming, the only workaround is an explicit typecast expression that forces the compiler to select the desired function:

  f((char *)0); //unambiguous but still a kludge

This workaround isn't ideal though. Often, programmers don't use an explicit cast expression because they're not aware of the problem. Additionally, the cast expression obfuscates the code and makes it less readable.

Using nullptr

The C++ standards committee has been aware of this problem for many years. However, a consensus about the right solution was reached only recently in the form of a new keyword that designated a null pointer value. nullptr is a C++0x reserved keyword designating an rvalue constant of type std::nullptr_t.

nullptr is implicitly converted to pointers and pointers to members. However, it's not convertible to bool or any of the numeric types of C++.

You can use nullptr as an initializer for all pointer types and in comparison expressions:

  const char *pc=str.c_str();
  if (pc!=nullptr)
    cout<<pc<<endl;
  int (A::*pmf)()=nullptr; //pointer to member function
  int A::*pmi=nullptr; //pointer to data member 

Any attempt to use nullptr as a non-pointer type will cause a compilation error:

  char* ps=nullptr; //OK
  char c=nullptr; //error, type mismatch
  int n=nullptr; //error, type mismatch

A Solution to a Thorny Problem

The use of nullptr eliminates the overload resolution problem:

  func(nullptr); //calls func (char*)
  func(0); //calls func(int)

You may explicitly instantiate objects of type std::nullptr_t, and use nullptr in sizeof expressions:

  cout<< typeid(nullptr).name(); 
  size_t sz= sizeof(nullptr); 

Throwing nullptr_t objects from a try block is also allowed:

  try
  {
   if(failure)
     throw nullptr; //OK
  }
  catch(std::nullptr_t) 
  {
   cerr<<"terminating!";
  }

Conclusion

Many programming languages have used a reserved keyword to designate a null pointer or a null reference for ages. The lack of a similar keyword in C++ programming has been a fertile source of bugs for many years. The addition of nullptr finally fixes a this longstanding loophole in the type system of C++. Microsoft's Visual Studio 2010 already supports this feature and so does GCC 4.6; other vendors will also implement this feature soon.

Related Articles



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: May 6, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT While you likely have very good reasons for remaining on WinXP after end of support -- an estimated 20-30% of worldwide devices still are -- the bottom line is your security risk is now significant. In the absence of security patches, attackers will certainly turn their attention to this new opportunity. Join Lumension Vice President Paul Zimski in this one-hour webcast to discuss risk and, more importantly, 5 pragmatic risk mitigation techniques …

  • The exponential growth of data, along with virtualization, is bringing a disruptive level of complexity to your IT infrastructure. Having multiple point solutions for data protection is not the answer, as it adds to the chaos and impedes on your ability to deliver consistent SLAs. Read this white paper to learn how a more holistic view of the infrastructure can help you to unify the data protection schemas by properly evaluating your business needs in order to gain a thorough understanding of the applications …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds