In C, NULL
is defined as (void *)0
whereas in C++ it is 0
. Why is it so?
In C I can understand that if NULL
is not typecast to (void *)
then compilers may/may not generate warning. Other than this, is there any reason?

- 362,284
- 104
- 897
- 1,065

- 1,087
- 1
- 9
- 18
-
7One interesting difference is that in C, you can implicitly cast from `void*` to any pointer type, and in C++ you cannot. – asveikau Aug 11 '11 at 17:30
-
2An implementation of either C or C++ can legally define `NULL` as `0`. A C implementation can define it as `((void*)0)`, but *not* as `(void*)0`. A macro defined in a standard C headers must be protected by parentheses so it can be used as if it were a single identifer; with `#define NULL (void*)0`, the expression `sizeof NULL` would be a syntax error. – Keith Thompson Mar 09 '17 at 18:58
3 Answers
Back in C++03, a null pointer was defined by the ISO specification (§4.10/1) as
A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero.
This is why in C++ you can write
int* ptr = 0;
In C, this rule is similar, but is a bit different (§6.3.2.3/3):
An integer constant expression with the value 0, or such an expression cast to type
void *
, is called a null pointer constant.55) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
Consequently, both
int* ptr = 0;
and
int* ptr = (void *)0
are legal. However, my guess is that the void*
cast is here so that statements like
int x = NULL;
produce a compiler warning on most systems. In C++, this wouldn't be legal because you can't implicitly convert a void*
to another pointer type implicitly without a cast. For example, this is illegal:
int* ptr = (void*)0; // Legal C, illegal C++
However, this leads to issues because the code
int x = NULL;
is legal C++. Because of this and the ensuing confusion (and another case, shown later), since C++11, there is a keyword nullptr
representing a null pointer:
int* ptr = nullptr;
This doesn't have any of the above problems.
The other advantage of nullptr
over 0 is that it plays better with the C++ type system. For example, suppose I have these two functions:
void DoSomething(int x);
void DoSomething(char* x);
If I call
DoSomething(NULL);
It's equivalent to
DoSomething(0);
which calls DoSomething(int)
instead of the expected DoSomething(char*)
. However, with nullptr
, I could write
DoSomething(nullptr);
And it will call the DoSomething(char*)
function as expected.
Similarly, suppose that I have a vector<Object*>
and want to set each element to be a null pointer. Using the std::fill
algorithm, I might try writing
std::fill(v.begin(), v.end(), NULL);
However, this doesn't compile, because the template system treats NULL
as an int
and not a pointer. To fix this, I would have to write
std::fill(v.begin(), v.end(), (Object*)NULL);
This is ugly and somewhat defeats the purpose of the template system. To fix this, I can use nullptr
:
std::fill(v.begin(), v.end(), nullptr);
And since nullptr
is known to have a type corresponding to a null pointer (specifically, std::nullptr_t
), this will compile correctly.

- 20,030
- 7
- 43
- 238

- 362,284
- 104
- 897
- 1,065
-
3Have a look at @Keith Thompsons' answer. A "null pointer constant" in C is any constant integer expression of value `0` optionally cast to `void*`. – Jens Gustedt Aug 10 '11 at 21:06
-
@Jens Gustedt- Can you review my edited answer to see if it's more correct? – templatetypedef Aug 10 '11 at 21:14
-
3almost perfect! Just one nit pick, you still seem to imply that `NULL` must be `(void*)0` in C. This isn't the case. Unfortunately it may be defined to just any null pointer constant, so it is not a very reliable concept in C. Therefore I personally think that `NULL` should just be avoided. And the reason some seem to prefer it to be of pointer type are more the rules for implicit argument promotion to functions without prototype, namely va_arg argument lists. But this is another story... – Jens Gustedt Aug 10 '11 at 21:54
In C, NULL
expands to an implementation-defined "null pointer constant". A null pointer constant is either an integer constant expression with the value 0, or such an expression cast to void*
. So a C implementation may define NULL
either as 0
or as ((void*)0)
.
In C++, the rules for null pointer constants are different. In particular, ((void*)0)
is not a C++ null pointer constant, so a C++ implementation can't define NULL
that way.

- 254,901
- 44
- 429
- 631
The C language was created to make it easier to program microprocessors. A C pointer is used to store the address of data in memory. A way was needed to represent that a pointer had no valid value. The address zero was chosen since all microprocessors used that address for booting up. Since it couldn't be used for anything else zero was a good choice to represent a pointer with no valid value. C++ is backward compatible with C so it's inherited that convention.
The requirement of casting zero when used as a pointer is only a recent add on. Later generations of C wanted to have more rigor (and hopefully fewer errors) so they started being more pedantic about syntax.

- 13,803
- 4
- 42
- 69
-
2From where do you get that there is a requirement to cast `0` to a pointer type. Neither C nor C++ have such a rule. In C you *may* have `(void*)0` as a null pointer constant, but nothing is forcing you to do so. – Jens Gustedt Aug 10 '11 at 20:52
-
1A null pointer is not required to have the internal representation 0, so the address zero is irrelevant. – ymett Aug 11 '11 at 10:54
-
-
@ymett: Do you have any documentation to backup your assertion? You completely contradict a lifetime of experience. – Jay Aug 11 '11 at 14:18
-
3I think the burden of proof goes the other way - the standard doesn't say anywhere that the null pointer must have any particular representation. Search for "null pointer representation" and you'll see it discussed innumerable times. Note that the constant `0` in source is required to be a null pointer constant - but that doesn't require the internal representation of the null pointer to be all bits zero, nor for it to be the same as the representation of integer zero. – ymett Aug 11 '11 at 14:41
-
1@ymett: Where did you get the idea that there's some hidden internal representation for a pointer? There isn't one. There is an option in many compilers to show the assembly language generated when you compile the code. You might have a look through it and see what it does with pointers. It's not magic. – Jay Aug 11 '11 at 16:57
-
2A pointer is represented in memory in some fashion (except where the compiler optimises it out). This representation is not present in source code. So there definitely is "some hidden internal representation". The normal representation is simply the address of the object pointed to. This obviously doesn't work for a null pointer because there is no object pointed to, so the compiler must use something else. All bits zero is often used, but the standard does not require this anywhere (and there have been compilers which used something else). – ymett Aug 14 '11 at 07:31
-
1It may well be true that every C implementation you've ever encountered has use all-bits-zero as its null pointer representation, but the language absolutely does not require it. – Keith Thompson Aug 15 '11 at 07:12
-
@Keith Thompson: According to your link C was created for pdp-7. The architectural difference between a pdp-7 and microprocessors developed twenty years later is minimal. Your point may be in some cases semantically correct but I don't see that the distinction has any real value – Jay Aug 16 '11 at 20:40
-
@Keith Thompson: logic also infers that the sun may not come up tomorrow but I submit planning for that eventuality is foolish. If NULL is a zero in every known case then arguing it "doesn't have to be" seems to have no value either. "What makes no difference, is no difference" – Jay Aug 16 '11 at 20:42
-
3@Jay: I've used a system that used the value 1 for a null pointer, because the CPU would trap on a reference to an odd address. Admittedly this wasn't a C compiler, but there was a real advantage to using a non-zero representation for null pointers. Neither of us knows what future systems will be like, but we've already seen mass re-writes necessitated by similar changes, such as code that depends on `*(int*)0 == 0`. And writing code that doesn't assume a null pointer is all-bits-zero really isn't that difficult. – Keith Thompson Aug 16 '11 at 20:46
-
1@Keith Thompson I'm all for being proactive. At the same time I think it's a waste of time and money to write code for problems that will not actually occur. Based on a lifetime of experience this will likely never occur. – Jay Nov 11 '13 at 15:57
-
2@Jay: You have a choice. You can write code that will fail on systems where a null pointer is not all-bits-zero; that code will likely work correctly on most systems. Or you can write code that makes no assumptions about how null pointers are represented; that code will work correctly on *all* systems. In the latter case, when (not if) your program misbehaves, you have one less possible cause to worry about. And here's the fun part: the second alternative is no more difficult than the first. – Keith Thompson Nov 11 '13 at 16:14
-
Your own post admits that the only system that you've ever used where this *might* be a problem wasn't even using a C compiler. This is the same logical flaw as premature optimization. You want people to waste time and effort to prevent things that will never happen. – Jay Nov 11 '13 at 16:35
-
@Jay If your code along the standard, you can be sure to have no problems. If you code *against* the standard, you may be run well in 999 of 1000 cases, but might eventually run into problems. So there is no reason to code against the standards. In the very most cases, the internal representation of a null pointer is plainly irrelevant. – glglgl Dec 19 '14 at 08:54
-
@glglgl if you could show me one instance where null is not zero I would consider this argument valid. Meanwhile it requires me to do extra work for an illusory benefit. I agree with your argument in principal but in the instance of the argument I think it's invalid. If standards add no value they have no value. – Jay Dec 19 '14 at 20:45
-
@Jay I just fail to see the extra work you talk about... And BTW, the [C FAQ shows some examples](http://c-faq.com/null/machexamp.html) of machines with null pointers which have not an all-zero representation. – glglgl Dec 19 '14 at 23:40
-
@glglgl All the machines listed are mainframes and/or obsolete. The 1 in 1000 chance you mention is more likely 1 in 1,000,000. The compiler has to do a lookup to find out what the text "NULL" means giving longer compiles. I have to type in three extra characters each time I use it. If it costs me a wasted microsecond for no benefit then it's too much. If it's in the FAQ then it's not just me who considers it a waste of time for no visible benefit. – Jay Dec 20 '14 at 02:08
-
1@Jay You still fail to see that "binary representation" and "representation as 0 in the program code" is distinct from each other. Using `0` is very fine - unless you have a variadic function where a cast is needed (with `NULL` as well because `NULL` can be `#define NULL 0`). So I still fail to see the point of the whole discussion. – glglgl Dec 20 '14 at 07:11