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.