When testing for NULL, I see a lot of code that uses !var. Is there a reason to use this kind of test as opposed to the more explicit var == NULL. Likewise would if (var) be a correct test for an item being non-null?

Both are valid, and mean the same thing if var is a pointer object. Personally, I strongly prefer var == NULL because it's more explicit. Many C programmers tend to value terseness over explicitness.
–
Keith ThompsonSep 30 '12 at 20:19

4 Answers
4

is in the second case the compiler have to issue a diagnostic if var is not of a pointer type and NULL is defined with a cast (like (void *) 0).

Also (as pointed by @bitmask in the comments) to use the NULL macro, you need to include a standard header that defines the NULL macro. In C the NULL macro is defined in several headers for convenience (like stddef.h, stdio.h, stdlib.h, string.h, etc.).

Otherwise the two expressions are equivalent and it is just a matter of taste. Use the one you feel more confortable at.

And for your second question if (var) is the same as if (var != NULL) with the difference noted above.

But it makes no difference if NULL is defined as just 0, which is perfectly legal. (I don't think C++ allows such a definition, but C does.)
–
Keith ThompsonSep 30 '12 at 20:17

@KeithThompson Actually, in C++ NULL is guaranteed to be 0. C and C++ are different in this case. In C, NULL can be a pointer (void*)0, and in theory it could also be something completely different, as long as it translated into a null pointer constant.
–
LundinSep 30 '12 at 20:53

as of the language: an integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.

as of the libraries: NULL is a macro that expands to the implementation-defined null pointer constant.

That means the expressions you give are equally "correct". The reason to prefer one form over another is largely a matter of taste.

That is, if you have a minimal compiler with no warnings beyond what is required by the standard. If you have a modern one, lets say one made after 1991, you'd get compiler warnings if you tried to compare a non-pointer variable against NULL.
–
LundinSep 30 '12 at 20:51

Arithmetic types and pointer types are collectively called scalar types.

The operand of the unary + or - operator shall have arithmetic type; of the ~ operator,
integer type; of the ! operator, scalar type.

The result of the logical negation operator ! is 0 if the value of its operand compares
unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int.
The expression !E is equivalent to (0==E).

The var == NULL version has one major advantage: it makes it possible for the compiler and static analysers to find one particular common bug.

Suppose "var" is not a pointer, but an allocated variable. if(!var) would then be a bug passing by undetected.

NULL is often declared as #define NULL ((void*)0). This declaration isn't mandatory by the standard, but one of the most common ones. A compiler with half-decent type checking would then be able to yield a warning for code like this:

Apart from the above advantage, it is also stylistically correct not to use the ! operator, since it is a logical operator, meant to be used on boolean variables, not pointers. It just works since C has no strong typing.

I would recommend to follow MISRA-C in this matter, which dictates that checks against NULL or zero should be made explicit. if(x != NULL) rather than if(x). The rationale for those rules is more readable code. It translates to the very same machine code anyhow, so there is no harm in making your code easier to read.