Hi,
is
if(pointer != NULL) ...
always exactly equivalent to
if(pointer) ...
for all pointer types, e.g.,
int *pointer;
Not if NULL is not defined, or someone nefarious has defined it incorrectly.
?
i.e., can I safely avoid typing "!= NULL" to shorten my NULL-
comparisons?
A nicer compromise is to use (ptr != 0). In C, an integer constant expression
whose value is zero serves as the language-defined null pointer constant,
when it appears in a context where it is converted to a pointer, whether
implicitly or by cast: assignment, comparison, (prototyped) parameter passing,
etc.
These are all good usage:
/* initialize pointer to null */
int *p = 0;
/* test for null pointer */
if (p == 0) ...
/* pass null pointer to a function */
#include <time.h>
/* ... */
time_t t = time(0);
You cannot subsitute a non-zero constant. For instance int *p = 1 is a
constraint violation that requires a diagnostic.
Once you get used to 0, you will realize that NULL doesn't buy anything.
It's a four-letter word for zero, which only raises a false sense of type
safety. For instance, the following is wrong:
/* wrong, but perhaps not obviously so */
printf("NULL = %p\n", NULL);
NULL may #defined to just 0, and so the above NULL is not actually
a null pointer constant (there is no conversion context to pointer type).
The same error is more obvious if a plain 0 is used:
printf("NULL = %p\n", 0);
Using 0 will drill it into your head that a conversion to pointer must
take place to make a null pointer; no conversion means that the 0 is
just the integer value 0.
/* correct */
printf("NULL = %p\n", (void *) NULL);
printf("NULL = %p\n", (void *) 0);
What's the use of a NULL that still needs the crutch of a pointer cast
to hold it up in some situations?
Incidentally, a constant zero cast to (void *) is also specially
blessed as a null pointer constant, a feature which is next to useless:
int *p = (void *) 0; /* correct but who would write this??? */
Some C implementations define NULL as this constant, using
#define NULL ((void *) 0) or equivalent. It would seem that this is better, but
if you have programs that rely on it, they have a portability bug, which may
show up when they are ported to a #define NULL 0 implementation.
Just say no to NULL and you don't have to worry about its pitfalls,