What is the difference between NULL and __null in C++?

NULL has been overtaken from C into C++ and - prior to C++11 - adopted its C meaning:

until C++11: The macro NULL is an implementation-defined null pointer constant, which may be an integral constant expression rvalue of integer type that evaluates to zero.

C++11 then introduced a dedicated null pointer literal nullptr of type std::nullptr_t. But - probably for backward compatibility - the macro NULL was not removed; its definition was just a bit relaxed in that compilers may now define it either as integral or as pointer type:

C++11 onwards: an integer literal with value zero, or a prvalue of type std::nullptr_t

If you use NULL, then you get implementation-defined behaviour in overload resolution. Consider, for example, the following code with a compiler that uses the integral-version of NULL-macro. Then a call using NULL as parameter passed to a function may lead to ambiguities:

struct SomeOverload {

    SomeOverload(int x) {
        cout << "taking int param: " << x << endl;
    }
    SomeOverload(void* x) {
        cout << "taking void* param: " << x << endl;
    }
};

int main() {

    int someVal = 10;

    SomeOverload a(0);
    SomeOverload b(&someVal);

    // SomeOverload c(NULL);  // Call to constructor is ambiuous
    SomeOverload d(nullptr);
}

So it is recommended to use nullptr where ever you want to express pointer type.

And don't use __null, as this is a compiler-specific, non-portable constant; nullptr, in contrast, is perfectly portable.


__null is a g++ internal thing that serves roughly the same purpose as the standard nullptr added in C++11 (acting consistently as a pointer, never an integer).

NULL is defined as 0, which can be implicitly used as integer, boolean, floating point value or pointer, which is a problem when it comes to overload resolution, when you want to call the function that takes a pointer specifically.

In any event, you shouldn't use __null because it's a g++ implementation detail, so using it guarantees non-portable code. If you can rely on C++11 (surely you can by now?), use nullptr. If not, NULL is your only portable option.


NULL is the old C symbol for a null pointer. C++ traditionally have used 0 for null pointers, and since the C++11 standard nullptr.

Considering that x doesn't seem to be a pointer then you can't initialize x to be a null pointer, and the __null symbol is perhaps some compiler-internal symbol for a null value (which is a concept that doesn't really exist in standard C++).

If you want x to initialized to some default state, then you have to rely on the MyClass default constructor to initialize the objects and its member variables to some suitable default values.

Tags:

C++

Null

Keyword