330

I know that in C++ 0x or NULL was replaced by nullptr in pointer-based applications. I'm just curious of the exact reason why they made this replacement?

In what scenario is using nullptr over NULL beneficial when dealing with pointers?

Archmede
  • 1,592
  • 2
  • 20
  • 37
Riptyde4
  • 5,134
  • 8
  • 30
  • 57
  • 3
    @BryanChen it's not. I don't want to know WHAT a nullptr is...I want to know why it was implemented and what the benefit is if you read the question correctly – Riptyde4 Dec 11 '13 at 03:05
  • 2
    read [this answer](http://stackoverflow.com/a/1283623/642626) – Bryan Chen Dec 11 '13 at 03:08
  • 7
    @BryanChen a couple of keywords in that are unfamiliar to me so that answer is unreadable....nevertheless, not a duplicate question just simply a question within the same topic with a potentially useful answer – Riptyde4 Dec 11 '13 at 03:11
  • 1
    maybe [this answer](http://stackoverflow.com/a/19014644/642626) is easier to understand – Bryan Chen Dec 11 '13 at 03:13

4 Answers4

458

nullptr has type std::nullptr_t. It's implicitly convertible to any pointer type. Thus, it'll match std::nullptr_t or pointer types in overload resolution, but not other types such as int.

0 (aka. C's NULL bridged over into C++) could cause ambiguity in overloaded function resolution, among other things:

f(int);
f(foo *);

(Thanks to Caleth pointing this out in the comments.)

Joe Z
  • 17,413
  • 3
  • 28
  • 39
  • 25
    @Cheersandhth.-Alf I have no idea how to respond to this other than the fact that I knew what I was asking and this was the easiest to understand explanation. – Riptyde4 Dec 11 '13 at 03:17
  • 11
    @Riptyde4: Shafik's answer is IMHO the most comprehensive. The quote there includes both the "ambigious overload" of this answer and the "templated argument type problem" of my answer, plus it's a nice reference. This answer is just a small part of the reasons. – Cheers and hth. - Alf Dec 11 '13 at 03:22
  • 2
    but we can always specify the type using typecast operator like f( (int) NULL ) or f((foo*) NULL ) as an alternative to resolve ambiguity... correct ? – Arjun Jun 16 '18 at 17:18
  • FWIW, I agree w/ Cheers that Shafik's answer is more comprehensive. In fact, I upvoted it some time ago. – Joe Z Aug 17 '20 at 22:54
  • Arjun: Yes, a cast can resolve the ambiguity, although I suppose there are still cases it cannot replace such as std::nullptr_t as an overload. Also, I don't think I'd use (int)NULL since semantically NULL is supposed to be pointer and may be actually be defined as nullptr. You're not guaranteed to get a 0 when to cast nullptr to int. Perhaps (int)0? – Joe Z Aug 17 '20 at 23:00
  • 6
    Nitpick: the type of `nullptr` is `std::nullptr_t`, which is not a pointer type. `nullptr` implicitly converts to any pointer type, and importantly *does not* convert to any integer type. – Caleth Apr 28 '21 at 11:38
  • Thanks, Caleth. You are correct. I've tweaked my wording accordingly. – Joe Z Sep 12 '21 at 03:11
  • It's short, clear, efficient, best answer in my opinion too. Thanks. – Elley Jul 26 '22 at 19:38
96

You can find a good explanation of why it was replaced by reading A name for the null pointer: nullptr, to quote the paper:

This problem falls into the following categories:

  • Improve support for library building, by providing a way for users to write less ambiguous code, so that over time library writers will not need to worry about overloading on integral and pointer types.

  • Improve support for generic programming, by making it easier to express both integer 0 and nullptr unambiguously.

  • Make C++ easier to teach and learn.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
63

Here is Bjarne Stroustrup's wordings,

In C++, the definition of NULL is 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem with NULL is that people sometimes mistakenly believe that it is different from 0 and/or not an integer. In pre-standard code, NULL was/is sometimes defined to something unsuitable and therefore had/has to be avoided. That's less common these days.

If you have to name the null pointer, call it nullptr; that's what it's called in C++11. Then, "nullptr" will be a keyword.

Deidrei
  • 2,125
  • 1
  • 14
  • 14
  • 8
    This doesn't really answer the question, only gives a source for the name... – Sinkingpoint Dec 11 '13 at 03:09
  • 9
    @Quirliom: I think that's the reason for the new keyword **nullptr** in C++11 – Deidrei Dec 11 '13 at 03:10
  • 1
    @Sinkingpoint is right. This is part way to being an answer because it explains one of the problems with `NULL`, but it doesn't explain how `nullptr` avoids that problem or why `nullptr` was actually introduced (which are the questions that the OP is actually asking). – Pharap May 28 '23 at 01:11
  • ok; thanks; but I'm sorry because I answered this question a rather long time ago; now I couldn't remember things on it.! – Deidrei Jun 08 '23 at 04:58
18

One reason: the literal 0 has a bad tendency to acquire the type int, e.g. in perfect argument forwarding or more in general as argument with templated type.

Another reason: readability and clarity of code.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • I agree but: The origin question is about the difference of NULL and nullptr ;-) – hfrmobile Jan 20 '20 at 12:36
  • 3
    @hrfmobile: `NULL` is a macro that could be and usually was defined as literal `0` (possibly with a type suffix). With current g++, version 9.2, it's instead defined as the intrinsic `__null`. With current Visual C++, 2019, it's defined as plain `0`. Thus, the first reason I gave applies *when* `NULL` is defined as a literal. The second reason always applies, but is more subjective. However, most people agree that all uppercase is an eyesore, shouting. Which is a main reason why that naming convention is used for macros. – Cheers and hth. - Alf Feb 07 '20 at 14:43
  • 2
    Well, for the type of `NULL`, the C++ standard could have added `std::nullptr_t` without adding `nullptr`, and define `#define NULL ((std::nullptr_t) 0)`, similar to what POSIX does in C: `#define NULL ((void *) 0)`. You wouldn't need a new keyword. – alx - recommends codidact Nov 27 '21 at 17:53
  • 2
    @alx I guess the use of a keyword precludes the all-too-prevalent `#undef NULL / #define NULL ` that can trip up anyone looking at `NULL` in the code thinking it means one thing when it means something else. After all, what's wrong with `#define true ((bool)1)`? – kbro Apr 14 '22 at 09:58