My personal issue with
NULL is that it is a macro, and I just don't like macros. That's it.
Yes, there are good uses for macros (anyone who ever needed
offsetof(), will agree), but most macro uses are... what was that word above,
bull feces?
A macro replaces some text of yours with some other text. You don't know if it happens, you don't see what happens, and the preprocessor doesn't care about the language's grammar, namespaces, or much of anything else. This can be a desaster, but it can also be a good thing in a few rare cases. It really depends.
If I remember correctly, there was a Stroustrup quote 10+ years ago that said something similar in respect to
NULL. I think it was like "use what you want, it's the same thing, but I'm using 0 because I don't like macros".
That's the correct way of looking at it, in my opinion. What does it matter if
NULL is standard or not? It is a descriptive token. If you want something to be descriptive, make it
NULL. If you don't want that, make it
0. Whatever you do, it's ok.
WM_CLOSE and
WM_LBUTTONDOWN are not standard, but they prevent you from wondering "What the hell do 16 and 513 stand for, what is going on here?". Or think about expressions like
INT_MAX-1To me,
if(ptr == 0) is pretty darn obvious, and I prefer this form in almost all cases. To other people, it is maybe not so obvious. In either case, I would use
const in preference to
#defines. While
#defines have their good uses, in many cases, a
const performs the same, but safer.
I #define nullptr 0 for the time being. It's being added to the C++ standard in the next revision as something different than 0 to give a little more safety to null pointers, so it's probably a better way to do it for now. Just remember to remove the #define when C++0x hits.
What is wrong with
static const void *nullptr = 0;? It obviously won't do for
foo_t* bar = nullptr; without a cast, but
if(foo == nullptr) should do just fine, and would bark if it encounters pointer/integral mismatches.
If you want to be able to assign
nullptr too, it obviously gets more complicated... but you could write something like:
template<typename T> void NullPtr(T& ptr) { ptr = static_cast<T>(const_cast<void*>(nullptr)); } and then
NullPtr(some_pointer); to zero that pointer. I haven't tested this, but I guess it should just work.