In the early days of C++ when it was bolted on top of C, you could not use NULL as it was defined as (void*)0
. You could not assign NULL to any pointer other than void*
, which made it kind of useless. Back in those days, it was accepted that you used 0
(zero) for null pointers.
To this day, I have continued to use zero as a null pointer but those around me insist on using NULL
. I personally do not see any benefit to giving a name (NULL
) to an existing value - and since I also like to test pointers as truth values:
if (p && !q)
do_something();
then using zero makes more sense (as in if you use NULL
, you cannot logically use p && !q
- you need to explicitly compare against NULL
, unless you assume NULL
is zero, in which case why use NULL
).
Is there any objective reason to prefer zero over NULL (or vice versa), or is all just personal preference?
Edit: I should add (and meant to originally say) that with RAII and exceptions, I rarely use zero/NULL pointers, but sometimes you do need them still.
There are a few arguments (one of which is relatively recent) which I believe contradict Bjarne's position on this.
Using
NULL
allows for searches on it's use and it also highlights that the developer wanted to use aNULL
pointer, irrespective of whether it is being interpreted by the compiler asNULL
or not.The example that everybody quotes is:
However, at least in my opinion, the problem with the above is not that we're using NULL for the null pointer constant, it's that we have overloads of 'foo' which take very different kinds of arguments. The parameter must be an
int
too, as any other type will result in an ambiguous call and so generate a helpful compiler warning.Even in the absence of C++ 0x, there are tools available today that verify that
NULL
is being used for pointers, and that0
is being used for integral types.std::nullptr_t
type.This is the newest argument to the table. The problem of
0
andNULL
is being actively addressed for C++ 0x, and you can guarantee that for every implementation that providesNULL
, the very first thing that they will do is:For those who use
NULL
rather than0
, the change will be an improvement in type-safety with little or no effort - if anything it may also catch a few bugs where they've usedNULL
for0
. For anybody using0
today....erm...well hopefully they have a good knowledge of regular expressions...Based on my knowledge it is good for prefer
nullptr
because0
isint
andNULL
is0L
(long type), if you have three different overload functionthen calling
foo(0)
call theint
one not the pointer and callingfoo(NULL)
maybe ambiguous for compiler because a long type can convert toint
andbool
andpointer
without any problem so how compiler know which function you are calling.this is an example of situation that you need to consider that don't use 0 and NULL as nullptr but if you use
0
andNULL
in context that compiler can interpret as pointer it will do that .I once worked on a machine where 0 was a valid address and NULL was defined as a special octal value. On that machine (0 != NULL), so code such as
would not work as you expect. You HAD to write
Although I believe most compilers define NULL as 0 these days I still remember the lesson from those years ago: NULL is not necessarily 0.
Someone told me once... I am going to redefine NULL to 69. Since then I don't use it :P
It makes your code quite vulnerable.
Edit:
Not everything in the standard is perfect. The macro NULL is an implementation-defined C++ null pointer constant not fully compatible with C NULL macro, what besides the type hiding implicit convert it in a useless and prone to errors tool.
NULL does not behaves as a null pointer but as a O/OL literal.
Tell me next example is not confusing:
Is because of all that, in the new standard appears std::nullptr_t
If you don't want to wait for the new standard and want to use a nullptr, use at least a decent one like the proposed by Meyers (see jon.h comment).
I always use:
NULL
for pointers'\0'
for chars0.0
for floats and doubleswhere 0 would do fine. It is a matter of signaling intent. That said, I am not anal about it.
Strange, nobody, including Stroustroup mentioned that. While talking a lot about standards and aesthetics nobody noticed that it is dangerous to use
0
inNULL
's stead, for instance, in variable argument list on the architecture wheresizeof(int) != sizeof(void*)
. Like Stroustroup, I prefer0
for aesthetic reasons, but one has to be careful not to use it where its type might be ambiguous.