Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should `!var` or `var == NULL` be used?

Tags:

c

pointers

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?

like image 333
Matt Avatar asked Sep 30 '12 19:09

Matt


4 Answers

The difference between:

!var

and

var == NULL

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.

like image 109
ouah Avatar answered Nov 13 '22 19:11

ouah


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:

int var = ...;
if(var == NULL)  // compiler warning, var is not a pointer

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.

like image 3
Lundin Avatar answered Nov 13 '22 17:11

Lundin


The ISO/IEC 9899 standard states that:

  1. 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.

  2. 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.

like image 2
geocar Avatar answered Nov 13 '22 17:11

geocar


From the C standard:

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).

So, that should answer your question.

like image 2
Alexey Frunze Avatar answered Nov 13 '22 19:11

Alexey Frunze