A

nullptr
nullptr is a representation of the null pointer that implicitly converts into any pointer type, but not into an integral type.

nullptr
nullptr, and its type
nullptr_t
nullptr_t, have been standardised in C++11, but its introduction predates the standard by at least 15 years, since the idea is contained in Scott Meyer‘s book Effective C++, 2nd edition, published in 1996.

Despite being a rather old idea, being in the standard for five years, being available in the compilers since even longer and having a quite straightforward fallback implementation, I still see a lot of new code using

0
0, or worse, 
NULL
NULL to represent null pointers.

Look at the “historical” test to show the reasons behind the creation of

nullptr
nullptr:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
void a(int x) { cout << "int" << endl; }
void a(void *y) { cout << "pointer" << endl; }
int main() {
a(0); // int overload
a((void*)0); // void * overload
a(nullptr); // void * overload
a(NULL); // ???
}
void a(int x) { cout << "int" << endl; } void a(void *y) { cout << "pointer" << endl; } int main() { a(0); // int overload a((void*)0); // void * overload a(nullptr); // void * overload a(NULL); // ??? }
void a(int x) { cout << "int" << endl; }
void a(void *y) { cout << "pointer" << endl; }
 
int main() {
    a(0);        // int overload
    a((void*)0); // void * overload
    a(nullptr);  // void * overload
    a(NULL);     // ???
}

This examples shows that if, during a refactoring, you decide to pass a

0
0 (instead of a pointer) to your function
a
a, you will end up calling a completely different overload, because no conversion is preferable to implicit conversion of a
0
0 into a
void*
void*, and this generates a silent bug. If you want to be sure to use the right overload, you have to explicitly cast your
0
0 to the right pointer type (in this case, a
void*
void*)

nullptr
nullptr doesn’t suffer of this problem, since it’s a different type (
std::nullptr_t
std::nullptr_t), an implicit conversion will take place anyway (and a better overload would be one taking an 
std::nullptr_t
std::nullptr_t type as parameter).

But wait, why those question marks when using

NULL
NULL? Why 
NULL
NULL should be worse than
0
0?

Well, to my surprise, when testing this I got an error (clang 3.7-based Apple compiler):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
error: call to 'a' is ambiguous
error: call to 'a' is ambiguous
error: call to 'a' is ambiguous

What ambiguity was the compiler complaining about? Well, apparently

NULL
NULL in clang is defined as
0L
0L, so both the
int
int and
void*
void* overload require exactly one implicit conversion to be selected.

On Visual Studio 2015, on the other hand,  the above code compiles and matches the

int
int overload, because it’s defined as a plain
0
0, but would complain with a
long
long overload.

As I said, this doesn’t happen with

nullptr
nullptr, because in normal circumstances you don’t need to write an overload to handle
std::nullptr_t
std::nullptr_t, so
nullptr
nullptrs are always implicitly converted into pointer types: ambiguity will only rise if you have your function overloaded on different pointer types, but that will generate a compile-time error, and not a silent bug.

 

2 Comments


  1. Hi,
    only out of curiosity. Here is your article in german. It’s from the 9th of January.
    http://www.grimm-jaud.de/index.php/blog/die-null-zeiger-konstante-nullptr

    Rainer

    Reply
    • Marco Foco

      Hi Rainer,

      I can’t read German, but from what google translate provided me, looks like I came up with the same idea you had few days ago.
      Interesting :)
      From what I get, your article seem to explore the problem more in depth, so if you agree I’ll modify my article and add a link at the end of mine, so German-speaking readers can read your article too.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.