In C, a
void* can be implicitly converted to any
T*. As such, making
void* is entirely appropriate.
But that’s profoundly dangerous. So C++ did away with such conversions, requiring you to do most pointer casts manually. But that would create source-incompatibility with C; a valid C program that used
NULL the way C wanted would fail to compile in C++. It would also require a bunch of redundancy:
T *pt = (T*)(NULL);, which would be irritating and pointless.
So C++ redefined the
NULL macro to be the integer literal 0. In C, the literal 0 is also implicitly convertible to any pointer type and generates a null pointer value, behavior which C++ kept.
Now of course, using the literal 0 (or more accurately, an integer constant expression whose value is 0) for a null pointer constant was… not the best idea. Particularly in a language that allows overloading. So C++11 punted on using NULL entirely over a keyword that specifically means “null pointer constant” and nothing else.