CoffeeTableEspresso
CoffeeTableEspresso

Reputation: 2652

How is NULL defined in C++?

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

Answers (1)

Fran&#231;ois Andrieux
Fran&#231;ois Andrieux

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

Related Questions