- In C++, the null constant
has always been problematic.
Lets take a look at why.
This is nullptr.cpp from
chapter three of the exercise file,
and you'll notice that we have an error down here
that says, "Call to 'f' is ambiguous".
And what's most interesting about this
is that if you're on a PC running
Visual Studio or Visual C++,
you may not even even see this error here.
This may not actually be an error,
and this is because of history
around the null constant
and the different way that it's used in C
than its used in C++.
Because C++ incorporates the entire definition
of the C language into its definition,
there's a few ambiguities that had to be resolved,
and this is one of them.
So, since the very beginning of the C language,
the constant value '0' has served double duty
as a null pointer constant.
The ambiguity was resolved by defining
a pre-processor marker called 'NULL'
which was typically defined as a
"Zero-value pointer to void".
C++ didn't adopt this behavior and
doesn't support the loose
type-casting of the 'void' pointer
like C does because this would be too ambiguous.
Notice here that we have two functions.
Both of them are named "f",
and one of them takes an integer,
and one of them takes a
constant character pointer, a "C string".
And so down here on calling that,
with a null value and
even though my 'NULL' is defined as,
a "long long 0", which is a common C definition,
neither of these functions
takes a 'long long' parameter
and 'long long' can often be
promoted to an integer,
but in this case its just too ambiguous
for this compiler and it really doesn't know
what to do with this 'NULL'
so we get an error instead
and this is very common in a lot of compilers,
a lot of systems, this causes an error
because it actually is ambiguous.
So the C++ standard does not
specify the exact value of the null macro.
So it's different on different systems.
On some systems like on this one
it might be the zero 'long long'.
On some systems including Microsoft Visual C++,
its just a zero.
So, if I change this definition
to something like void pointer to zero,
so now I have a void pointer type that is NULL.
It's a pointer with a value of zero .
When I try to build this, its still ambiguous
because this function, while it takes a pointer,
it doesn't take a pointer to void.
It takes a pointer to a character
so that doesn't work.
If I change this to just be a zero by itself,
and I build, it still fails.
So C++ 11 defines a new keyword and it's called
"nullptr" like this.
And now this is no longer ambiguous.
So the 'nullptr' keyword in the spec
is specified as a null pointer constant
that can be converted to a NULL pointer value
or a NULL member pointer value.
So, this can be automatically promoted
to a pointer value of any type
and since we have a function
that takes a pointer value,
we know which one it's going to call.
So when I build this,
it says, "the pointer is 0."
And if instead, I call this with a number '0'
and build it, it says, "the int is 0",
because I'm passing it in 'int'
and its calling this integer function
and when I pass it the 'nullptr',
its calling the pointer function
and it says, "the pointer is 0."
So the 'nullptr' constant provides a much needed
value to be used where the traditional
null void pointer value
would have been used in C but
doesn't work in C++.
It resolves the ambiguity problem
and it can be used in the context of
any pointer type.