In C, NULL
is normally #defined
as either 0
or ((void *)0)
. I expected this to be similar in C++, and many answers on stack overflow seem to suggest that's the case as well. However, when I try to compile the following program:
#include <stdio.h>
void f(int x) {
printf("void *\n");
}
void f(void *x) {
printf("int\n");
}
int main(void) {
f(0); // int
f((void *)0); // void *
f(nullptr); // void *
f(NULL); // why is this ambiguous?
return 0;
}
I'm told by my compiler that f(NULL)
is ambiguous. Specifically, my compiler says:
sample.cpp:15:5: error: call to 'f' is ambiguous
f(NULL);
^
sample.cpp:3:6: note: candidate function
void f(void *x) {
^
sample.cpp:7:6: note: candidate function
void f(int x) {
^
1 error generated.
If NULL
was defined as either 0
or ((void *)0)
, I'd expect it to resolve to the int
overload or the void *
overload of f
, but it doesn't. If NULL
was defined to be nullptr
for some reason, that would also resolve to the void *
overload. What gives?
I compiled on a Mac with g++ --std=c++11 sample.cpp
for anyone trying to replicate this. Haven't tried it on other platforms.
For an example of an answer that talks about NULL
in C++, see here.
EDIT: I know to always use nullptr
over NULL
when possible in C++. This question came up when I tried to come up with a few examples of why to show someone.
Null means having no value; in other words null is zero, like if you put so little sugar in your coffee that it's practically null. Null also means invalid, or having no binding force.
The null pointer constant is always 0. The NULL macro may be defined by the implementation as a naked 0 , or a cast expression like (void *) 0 , or some other zero-valued integer expression (hence the "implementation defined" language in the standard). The null pointer value may be something other than 0.
The type of NULL may be either an integer type or void * . This is because the C standard allows it to be defined as either an integer constant expression or the result of a cast to void * .
What is a NULL value? A NULL value is a special marker used in SQL to indicate that a data value does not exist in the database. In other words, it is just a placeholder to denote values that are missing or that we do not know.
From cppreference since C++11 :
an integer literal with value zero, or a prvalue of type
std::nullptr_t
On your platform, it seems if you add a long int
overload it resolves the ambiguity. I therefore assume that NULL
on your platform with those flags is a long int
with the value 0, or 0l
: demonstration. I don't know why they chose 0l
over just 0
, but it is an integer literal with the value zero, so it seems like that's allowed.
This means that the result of this program depends on your compiler and your compilation flags, so beware. The use of nullptr
is preferred.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With