C++ 2011: nullptr

C++ used to lack a special value to indicate a null pointer. It used 0 for this purpose, something that was inherited from C. This led to some problems, which we'll show in this article. The new standard introduces a new reserved word nullptr, to designate a constant rvalue that represents a null pointer.


In C++ a null pointer is:

A null pointer constant is an integral constant expression (expr.const) rvalue of integer type that evaluates to zero.

This was inherited from C where

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.

Since there is no keyword in the language for a null pointer, both C and C++ compiler provide an implementation-dependent macro called NULL. In VC++ and GCC this is defined as:

#ifdef __cplusplus
#define NULL    0
#define NULL    ((void *)0)

Integer 0 implicitly converts to any pointer type. The use of 0 as a special value for null pointers can lead to some issues, the most important being with calling overloaded functions. Let's look at these two overloaded functions:

void foo(int)   {cout << "int" << endl;}
void foo(char*) {cout << "pointer" << endl;}

The q uestion is, which of the two would be called for foo(0)? The answer is the first one. To be able to call the second one with a null pointer an explicit cast to char* should be made, i.e. foo((char*)0). On the other hand, the following line of code is valid and calls that constructor of std::basic_string that takes a char*:

string str(false);

The nullptr Reserved Word

The new standard introduces a reserved word called nullptr to represent a null pointer. It designates a constant rvalue of type decltype(nullptr):

typedef decltype(nullptr) nullptr_t;

The nullptr_t type:

  • Is a typedef for decltype(nullptr)
  • Is a POD type convertible to a pointer type and pointer-to-member type
  • Objects of this type can be copied and thrown
  • It is possible to take the address of a nullptr_t object
  • reinterpret_cast to/from a nullptr_t object is possible
  • nullptr_t matches a T* and a T::* partial specialization

The nullptr:

  • Is a literal (just like 0 or false)
  • The address of nullptr cannot be taken
  • Can be used with sizeof, typeid and ternary conditional operator

It is important to note that the standard library macro NULL is not (re-)defined to nullptr; the result of that would be a lot of broken code.

It is possible to use 0 (NULL) and nullptr interchangeably (which is important for compatibility), like in the following examples:

int* p1 = 0;
int* p2 = nullptr;

if(p1 == 0) {}
if(p2 == 0) {}
if(p1 == nullptr) {}
if(p2 == nullptr) {}
if(p1 == p2) {}
if(p2) {}

It is not possible however to assign nullptr to an integer value, nor to compare nullptr to an integer.

int n1 = 0;             // ok
int n2 = nullptr;       // error

if(n1 == nullptr) {}    // error
if(n2 == nullptr) {}    // error
if(nullprt) {}          // error

Also, because nullptr is an rvalue constant, it's not possible to assign it a value.

nullptr = 0;

For the overloading problem presented in the previous paragraph, use of nullptr would call the overload that takes a char*.

void foo(int)   {cout << "int" << endl;}
void foo(char*) {cout << "pointer" << endl;}

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

nullptr can be used with the ternary conditional operator:

int* p1 = ...;
int* p2 = true ? p1 : nullptr;

However, the following cases are erroneous:

int* p2 = true ? 0 : nullptr;       // incompatible types
int n1 = true ? nullptr : nullptr;  // nullptr cannot be converted to int
int n2 = true ? 0 : nullptr;        // incompatible types

Given these two template functions:

template<typename T>
void fooptr(T* t);

template<typename T>
void foo(T t);

The following cases are possible:

fooptr((int*)0);        // type T deduced to int
fooptr((int*)nullptr);  // type T deduced to int

foo(0);                 // type T deduced to int
foo((int*)0);           // type T deduced to int*
foo(nullptr);           // type T deduced to nullptr_t
foo((int*)nullptr);     // type T deduced to int*

while these are errors:

fooptr(0);              // error, type T cannot be deduced
fooptr(nullptr);        // error, type T cannot be deduced


The new C++ standard defines a reserved word nullptr (representing a constant rvalue of type nullptr_t) that designates a null pointer. For compatibility reasons 0 can still be used as null pointer, and 0 and nullptr can be used interchangeably; also for compatibility reasons, macro NULL will not be redefined to nullptr.

About the Author

Marius Bancila

Marius Bancila is a Microsoft MVP for VC++. He works as a software developer for a Norwegian-based company. He is mainly focused on building desktop applications with MFC and VC#. He keeps a blog at www.mariusbancila.ro/blog, focused on Windows programming. He is the co-founder of codexpert.ro, a community for Romanian C++/VC++ programmers.

Related Articles


  • Software Architect

    Posted by Ashwani Kumar on 07/26/2014 09:02am

    Very useful and clear article.

  • thanks

    Posted by liveevil on 12/29/2011 09:22pm

    thanks for sharing the latest information about the newly C++2011 standardo Reply

  • C++ 2011: nullptr

    Posted by Cql_liliang on 11/18/2011 10:44pm

    hi ,  Marius Bancila , maybe you have an error. 
    if(nullprt) {}          // error
    is not if(nullptr){}  ?

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

Top White Papers and Webcasts

  • Moving from an on-premises environment to Office 365 does not remove the need to plan for disruptions or reduce the business risk requirements for protecting email services. If anything, some risks increase with a move to the cloud. Read how to ease the transition every business faces if considering or already migrating to cloud email. This white paper discusses: Setting expectations when migrating to Office 365 Understanding the implications of relying solely on Exchange Online security Necessary archiving …

  • Thanks to the Internet of Things (IoT), physical assets are turning into participants in real-time global digital markets. The countless types of assets around us will become as easily indexed, searched and traded as any online commodity. While some industries will be tougher to transform than others – those with physical limitations, such as manufacturing, will be harder to digitize – untold economic opportunities exist for growth and advancement. Our research shows this will create a new "Economy …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date