74

In C++11 the nullptr keyword was added as a more type safe null pointer constant, since the previous common definition of NULL as 0 has some problems.

Why did the standards committee choose not to call the new null pointer constant NULL, or declare that NULL should be #defined to nullptr?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
user253751
  • 57,427
  • 7
  • 48
  • 90

7 Answers7

76

Stephan T. Lavavej (member of the C++ standard committee) explained that once in a talk (55:35):

While an implementation is allowed to #define NULL nullptr, it would break quite some uses like

int i = NULL;

and apparently there are plenty of those. So they could not force the change.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • 3
    I had hoped they'd at least *deprecate* this, so that NULL can be defined as nullptr in the future... (Or so nullptr could be called NULL and nullptr_t could have a deprecated conversion to int) – user253751 Aug 31 '15 at 01:01
  • @immibis Well it is not *guaranteed* to work, at least not past C++11. See [here](http://en.cppreference.com/w/cpp/types/NULL) for reference. So something like `int i = NULL;` is "not portable". Still works on all implementations afaik, but well, it does not need to, so it is more than deprecated. – Baum mit Augen Aug 31 '15 at 01:06
  • 5
    For a similar example to the `int` case, I've occasionally come across code where someone has "null-terminated" their string with `str[end_pos] = NULL;`. – paddy Aug 31 '15 at 02:01
  • 14
    `int i = NULL;` is and has always been evil. Why would you want do do this? – TNA Aug 31 '15 at 08:46
  • 1
    I think Stephan T. Lavavej was referring to *defining `NULL` as `nullptr`*, after `nullptr` had already been introduced into (drafts of) C++11. However, a similar rationale appears in [N1601](http://open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1601.pdf), which introduced `nullptr`. – dyp Aug 31 '15 at 08:57
  • 9
    @TNA Well, C is kind of evil in this way. It's just like using `str[end_pos] = NULL` or `str[end_pos] = 0`, or using `13` instead of `\r`, for example - all commonly used. Types aren't a big deal in C... Another example is the wildly misused `long`, especially when combined with the way pointers are routinely cast to `int` or `long`. The guy who "invented" `int i = NULL` might have thought it's a pretty obvious way of saying "now the `int i` is initialised to a default value". It's sad, but there's lot of similar practices in C. – Luaan Aug 31 '15 at 08:57
  • 4
    @Luaan Don't bring C into this. `str[end_pos] = NULL` and `int i = NULL` are *only* guaranteed to be valid in C++. (C doesn't actually specify the definition of `NULL`, but it's not an int in any sane implementation; it's only in C++ where `NULL` is required to be an integer.) – Alex Celeste Aug 31 '15 at 16:31
  • 10
    @Luaan C allows `NULL` to be defined to `((void*) 0)` and already makes `int i = NULL;` technically illegal. – jamesdlin Aug 31 '15 at 19:48
  • @Leushenko Mostly true. But the very first thing I find on Google is this - http://www.c4learn.com/c-programming/c-null-pointer/ , defining NULL as `#define NULL 0` and warning not to use it anywhere but in a pointer, of course. Sadly, I'm pretty sure a lot of people tend to simply copy code like this without reading the text, and start using it as common practice. Double sadly, it's actually conforming to C99 spec - `An integer constant expression with the value 0, or such an expression cast to type void*, is called a null pointer constant.`. `(void*)0` is a better option, of course. – Luaan Sep 01 '15 at 07:48
  • 2
    @Leushenko "`int i = NULL` [is] only guaranteed to be valid in C++...`NULL` [is] not an int in any sane implementation" -- GCC 5.1 doesn't complain about `int i = NULL` even with `-Wall -Wextra -pedantic -ansi`. But you're right, `NULL` is defined to be `((void *)0)`. Automatic conversion of the null pointer into the 0 integer is nonetheless allowed, apparently (and is even [called out in the CERT secure coding standard](https://www.securecoding.cert.org/confluence/display/c/INT36-C.+Converting+a+pointer+to+integer+or+integer+to+pointer) as something that's expressly allowed). – Kyle Strand Sep 02 '15 at 18:48
  • 4
    I think breaking such egregious behavior is OK. Developers should not be allowed to write stupid code just because it runs ;) – Ky - Sep 08 '15 at 18:51
  • 1
    @BenC.R.Leggiero Well don't forget that most code is written on a schedule. You can only go so far with breaking user code before people just stop using your product. – Baum mit Augen Sep 08 '15 at 19:03
  • @M.M that was never standard conformant, `NULL` can just as well be `0L` which causes an ambiguity for your snippet. – K-ballo Sep 09 '15 at 01:41
  • 3
    @BenLeggiero then C++11 would end up like D - it's better than old C++, but nobody is using it. Some companies need to rely on 30-year-old codebases for their daily business, you know? – minexew Nov 17 '16 at 10:17
  • @minexew nah it'd be like Swift. Swift breaks code with every version update, but for the greater good and they provide migration tools that update your code for you. Existing compiled binaries aren't broken and you can still compile old code by using an old compile. That's the way to do it! – Ky - Nov 17 '16 at 11:43
  • @BenLeggiero How is Swift even comparable to C++? It's not a mature language, so nobody expects it to be stable, and is vastly less complex, which makes automatic code update feasible. – minexew Nov 17 '16 at 12:51
  • @minexew They are very comparable in that they both compile to assembly, they both evolve, they're cross-compatible, and they both aim to be a very widely-used language. Also, though Swift might seem less complex on the surface, in practice it can do anything C++ can do, just in different ways. – Ky - Nov 17 '16 at 14:59
  • 2
    So C++ has created nullptr to solve the problem they caused by defining NULL as 0 instead of (void *)0 like C does, thus unnecessarily increasing the complexity of C++ even further. – Gungwald May 24 '22 at 05:01
  • @Leushenko: as [another answer](https://stackoverflow.com/questions/32302615/why-not-call-nullptr-null/32469629#32469629) points out, C++11 does *not* require that `NULL` is defined as an integral constant. It *could* be defined as `nullptr`, but isn't required to be. Conforming C++11 implementations are allowed to "break" terribly confused code that uses NULL in non-pointer contexts. Mainstream implementations choose not to because of garbage like this in old codebases, and ISO C++ intentionally gives them that choice. – Peter Cordes Dec 21 '22 at 19:36
42

nullptr is of pointer type , while NULL has the tendency to be integer, and sometimes in overloaded functions, you need to be clear that you are using a pointer and not an integer - this is when nullptr comes in handy.

So to really answer your question, NULL and nullptr serve two different purposes and redefining one to another will probably break a lot of things in already existent code bases.

Beside that, check this from Bjarne Stroustrup's website:

Should I use NULL or 0?

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.

ecm
  • 2,583
  • 4
  • 21
  • 29
Kiloreux
  • 2,220
  • 1
  • 17
  • 24
  • 1
    But that's the question - why not change NULL to be what nullptr is? – user253751 Sep 01 '15 at 12:12
  • 2
    @immibis because you can not initialize int variables (just an example) to pointer type NULL (which is nullptr), that will be a great a problem. – Kiloreux Sep 01 '15 at 18:12
  • 8
    Technically, `nullptr` is not of pointer type, but of type `nullptr_t`. –  Sep 07 '15 at 09:22
  • @Hurkyl , sure i was just trying to make the concept clear, maybe you should edit the answer to include that . – Kiloreux Sep 07 '15 at 09:25
  • 1
    Me, I would say that `NULL` and `nullptr` serve the *identical* purpose — in well-written code, at least. – Steve Summit Dec 21 '22 at 14:22
9

NULL is not type safe. For historical reason it was defined as 0 without casting, and the compiler silence warning of casting number to pointer on this special zero.

For instant, you can do:

void* p = 0;

but not this without implicit casting:

void* p = 1234;

the side effect is that it can be abused as number values, as other answer mentioned.

nullptr improve this by enforcing it is a pointer, you can't assign this to an integer. Since the behaviour is changed, a new name is created for backward compatibility.

Also note that, nullptr is handled by the compiler, its actual value is not exposed to user (like zero in case of NULL). It's much easier to have architecture dependent value, say 0xdeadbeef, without affect programmer's code logic.

Non-maskable Interrupt
  • 3,841
  • 1
  • 19
  • 26
  • 2
    Now I'm hungry for some dead beef. – dub stylee Aug 31 '15 at 18:46
  • 4
    @dubstylee 0xfeedface 0xdeadbeef? 0xfeedface 0xcafef00d! (We used to have a system with 4-digit hex displays, and everyone in the group got to know almost every 4-letter word containing only the characters a, b, c, d, e, f, i & o, and used them to talk to each other.) – Erik Johnson Aug 31 '15 at 19:28
7

Without actually sitting in on the discussion in the standards committee, it's hard to say for sure, but I would think because it would break some code that uses NULL in a meaning where nullptr isn't sufficiently compatible. And breaking old code is never a good idea.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
3

Why did the standards committee choose not to call the new null pointer constant NULL

Presumably because the new null pointer is a keyword, and keywords cannot be #defined, so calling it NULL would have made inclusion of any C header likely ill-formed.

or declare that NULL should be #defined to nullptr?

The standards committee does allow NULL to be #defined to nullptr, but it does not require it.

C++11 18.2 Types [support.types]/2: The macro NULL is an implementation-defined C++ null pointer constant in this International Standard.

C++11 4.10 Pointer conversions [conv.ptr]/1: A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t.

Backwards compatibility is not a concern here, any use of NULL that assumes it is a form of the integer 0 is not standard conformant. Implementations might choose not to do it to condone this kind of evil behavior.

K-ballo
  • 80,396
  • 20
  • 159
  • 169
2

I will demonstrate a case where the decision to define nullptr as a different type helps preventing bugs.

Consider these functions:

void foo(int);
void foo(char *);

int main()
{
    foo(NULL); // oops
}

In C++98, the code above calls the foo(int) function, because NULL is replaced by 0, which is most likely not what you intended to.

But if you call foo(nullptr) it calls the correct one -- foo(char*).

Minas Mina
  • 2,058
  • 3
  • 21
  • 35
0

Thenullptr is introduced for type safety and for clarity (probably to stop the initialization of non-pointer types using NULL).

The NULL(int type) is not changed to nullptr(pointer type) to avoid confusion and to ensure backward compatibility.

Thus, the standard committee train of thought is probably related to smooth transition from the old to new notation without causing ambiguities or braking any already existing code.

Ziezi
  • 6,375
  • 3
  • 39
  • 49
  • Making NULL a pointer type *causes* confusion? If anything I'd think it would *avoid* confusion. – user253751 Sep 08 '15 at 00:23
  • @immibis It says: _"The NULL(int type) is not changed to nullptr(pointer type)" to avoid confusion_ and is in the context of the question. The confusion concerns the `types`, that is why I've explicitly put them right after to clarify. Of course making a pointer `NULL` doesn't cause a confusion, but the _accepted answer_ shows you an example of why NULL's type is not changed to `nullptr`. – Ziezi Sep 08 '15 at 09:58