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?
相关问题
- Sorting 3 numbers without branching [closed]
- Multiple sockets for clients to connect to
- How to compile C++ code in GDB?
- Do the Java Integer and Double objects have unnece
- Why does const allow implicit conversion of refere
Back in C++03, a null pointer was defined by the ISO specification (§4.10/1) as
This is why in C++ you can write
In C, this rule is similar, but is a bit different (§6.3.2.3/3):
Consequently, both
and
are legal. However, my guess is that the
void*
cast is here so that statements likeproduce 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:However, this leads to issues because the code
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: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:If I call
It's equivalent to
which calls
DoSomething(int)
instead of the expectedDoSomething(char*)
. However, withnullptr
, I could writeAnd 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 thestd::fill
algorithm, I might try writingHowever, this doesn't compile, because the template system treats
NULL
as anint
and not a pointer. To fix this, I would have to writeThis is ugly and somewhat defeats the purpose of the template system. To fix this, I can use
nullptr
:And since
nullptr
is known to have a type corresponding to a null pointer (specifically,std::nullptr_t
), this will compile correctly.Hope this helps!
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 tovoid*
. So a C implementation may defineNULL
either as0
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 defineNULL
that way.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.