Checking for NULL pointer in C/C++
if (foo)
is clear enough. Use it.
I'll start off with this: consistency is king, the decision is less important than the consistency in your code base.
In C++
NULL is defined as 0
or 0L
in C++.
If you've read The C++ Programming Language Bjarne Stroustrup suggests using 0
explicitly to avoid the NULL
macro when doing assignment, I'm not sure if he did the same with comparisons, it's been a while since I read the book, I think he just did if(some_ptr)
without an explicit comparison but I am fuzzy on that.
The reason for this is that the NULL
macro is deceptive (as nearly all macros are) it is actually 0
literal, not a unique type as the name suggests it might be. Avoiding macros is one of the general guidelines in C++. On the other hand, 0
looks like an integer and it is not when compared to or assigned to pointers. Personally I could go either way, but typically I skip the explicit comparison (though some people dislike this which is probably why you have a contributor suggesting a change anyway).
Regardless of personal feelings this is largely a choice of least evil as there isn't one right method.
This is clear and a common idiom and I prefer it, there is no chance of accidentally assigning a value during the comparison and it reads clearly:
if (some_ptr) {}
This is clear if you know that some_ptr
is a pointer type, but it may also look like an integer comparison:
if (some_ptr != 0) {}
This is clear-ish, in common cases it makes sense... But it's a leaky abstraction, NULL
is actually 0
literal and could end up being misused easily:
if (some_ptr != NULL) {}
C++11 has nullptr
which is now the preferred method as it is explicit and accurate, just be careful about accidental assignment:
if (some_ptr != nullptr) {}
Until you are able to migrate to C++0x I would argue it's a waste of time worrying about which of these methods you use, they are all insufficient which is why nullptr was invented (along with generic programming issues which came up with perfect forwarding.) The most important thing is to maintain consistency.
In C
C is a different beast.
In C NULL
can be defined as 0
or as ((void *)0)
, C99 allows for implementation defined null pointer constants. So it actually comes down to the implementation's definition of NULL
and you will have to inspect it in your standard library.
Macros are very common and in general they are used a lot to make up for deficiencies in generic programming support in the language and other things as well. The language is much simpler and reliance on the preprocessor more common.
From this perspective I'd probably recommend using the NULL
macro definition in C.
I use if (ptr)
, but this is completely not worth arguing about.
I like my way because it's concise, though others say == NULL
makes it easier to read and more explicit. I see where they're coming from, I just disagree the extra stuff makes it any easier. (I hate the macro, so I'm biased.) Up to you.
I disagree with your argument. If you're not getting warnings for assignments in a conditional, you need to turn your warning levels up. Simple as that. (And for the love of all that is good, don't switch them around.)
Note in C++0x, we can do if (ptr == nullptr)
, which to me does read nicer. (Again, I hate the macro. But nullptr
is nice.) I still do if (ptr)
, though, just because it's what I'm used to.
In my experience, tests of the form if (ptr)
or if (!ptr)
are preferred. They do not depend on the definition of the symbol NULL
. They do not expose the opportunity for the accidental assignment. And they are clear and succinct.
Edit: As SoapBox points out in a comment, they are compatible with C++ classes such as auto_ptr
that are objects that act as pointers and which provide a conversion to bool
to enable exactly this idiom. For these objects, an explicit comparison to NULL
would have to invoke a conversion to pointer which may have other semantic side effects or be more expensive than the simple existence check that the bool
conversion implies.
I have a preference for code that says what it means without unneeded text. if (ptr != NULL)
has the same meaning as if (ptr)
but at the cost of redundant specificity. The next logical thing is to write if ((ptr != NULL) == TRUE)
and that way lies madness. The C language is clear that a boolean tested by if
, while
or the like has a specific meaning of non-zero value is true and zero is false. Redundancy does not make it clearer.