Reputation: 2652
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.
Upvotes: 7
Views: 534
Reputation: 29013
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.
Upvotes: 9