Comparing pointers to NULL

C

Charlie Zender

Hi,

is

if(pointer != NULL) ...

always exactly equivalent to

if(pointer) ...

for all pointer types, e.g.,

int *pointer;

?

i.e., can I safely avoid typing "!= NULL" to shorten my NULL-
comparisons?

Thanks,
Charlie
 
G

Guest

| Hi,
|
| is
|
| if(pointer != NULL) ...
|
| always exactly equivalent to
|
| if(pointer) ...
|
| for all pointer types, e.g.,
|
| int *pointer;
|
| ?
|
| i.e., can I safely avoid typing "!= NULL" to shorten my NULL-
| comparisons?

Yes, you can. I usually do. I choose to do it like "== NULL" or "!= NULL"
in certain cases where it might make sense to express it like that for the
benefit of the reader. Those cases are rare.
 
K

Keith Thompson

Charlie Zender said:
is

if(pointer != NULL) ...

always exactly equivalent to

if(pointer) ...

for all pointer types, e.g.,

int *pointer;

?
Yes.

i.e., can I safely avoid typing "!= NULL" to shorten my NULL-
comparisons?

You can do it with no change in semantics. I wouldn't do it
myself; I find
if (pointer != NULL)
clearer than
if (!pointer)
especially if "pointer" actually has a name that doesn't make it
entirely clear that it's a pointer.
 
E

Eric Sosman

Keith said:
You can do it with no change in semantics. I wouldn't do it
myself; I find
if (pointer != NULL)
clearer than
if (!pointer)

Not only clearer than, but opposite to.
 
K

Keith Thompson

Eric Sosman said:
Keith Thompson wrote: [...]
You can do it with no change in semantics. I wouldn't do it
myself; I find
if (pointer != NULL)
clearer than
if (!pointer)

Not only clearer than, but opposite to.

D'oh!
 
A

arnuld

Yes, if you're employed by the Ministry of Silly Walks.
Silly Charlie, silly Charlie, chilly Sarlie, barley farley, oh my darlie
Clementarlie. You can also leave out most of the white space in your
program source, and shorten things even more dramaticallarlie.
Huzzarlie!


I thought it was a matter of style but you reacted like if OP has
violated ANSI standard.
 
K

Kaz Kylheku

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,
 
K

Keith Thompson

Kaz Kylheku said:
Not if NULL is not defined, or someone nefarious has defined it incorrectly.

Or somebody has hacked the compiler so it treats "!=" as "==",
or the memory containing pointer is hit by a cosmic ray at just
the wrong moment.

There are legitimate reasons to avoid NULL (not reasons that I agree
with, but legitimate ones); concern that the implementation might
have defined it incorrectly isn't one of them. Yes, user code could
redefine NULL (the behavior is undefined but is likely to result in
the redefinition taking effect), but I really don't think that's
worth worrying about. You need to include one of the several
standard headers that defines NULL, but you've probably already
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.

Quite correct, and perfectly safe, but I still prefer NULL.
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 buys clarity. I use NULL for a null pointer constant for the
same reason I use 0.0 for a floating-point constant or '\0' for
a character constant. I could use 0 in all these cases, and rely
with complete confidence on the compiler to do the right implicit
conversion (well, in most cases). But I'm not just communicating
with the compiler. I'd be happier if the language had a keyword
that specifically represents a null pointer constant, but since it
doesn't NULL will do.
It's a four-letter word for zero, which only raises a false sense of type
safety.

C's use of 0 for null pointer constants is, quite frankly, a bit
of an ugly hack.
For instance, the following is wrong:

/* wrong, but perhaps not obviously so */
printf("NULL = %p\n", NULL);

Arguments to variadic functions are a special case; you always have
to take extra care to achieve type consistency. Passing ``sizeof
something'' to a function expecting an int is perfectly safe if the
function isn't variadic (and a prototype is visible, and the value
doesn't exceed INT_MAX), but for a variadic function the behavior
is undefined. NULL isn't the trap; printf is.
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).

Yes, it actually is a null pointer constant. The standard's
definition of the term doesn't require it to be converted to a pointer
type; it says that it yields a null pointer *if* it's converted to a
pointer type. But yes, the fact that it's a null pointer constant
isn't helpful in this case. So you have to remember to write
(void*)NULL. (And how often do you pass a null pointer constant to
printf anyway?)

[snip]
Just say no to NULL and you don't have to worry about its pitfalls,

Just understand what the pitfalls are and you don't have to worry
about them.

And are there any real pitfalls other than variadic functions?
 
J

J. F. Lemaire

arnuld said:


It/is/amatterofstyle;ifErichadintendedtopointoutastandard
violationhewouldhavequotedchapterandverse.Itispossibleto
chooseastylethatisperfectlylegalbutneverthelessrathersilly.
IamnotconvincedthatCharlieZender'ssuggestionisall/that/silly
butEricclearlythinksso.

I know you were being facetious, but the above paragraph is
syntactically incorrect, and so doesn't constitute a very good analogy
with legal white space removal in C sources.

JFL
 
A

August Karlstrom

Eric said:
Keith Thompson wrote: [...]
You can do it with no change in semantics. I wouldn't do it
myself; I find
if (pointer != NULL)
clearer than
if (!pointer)

Not only clearer than, but opposite to.

Illustrates clearly why `if (pointer != NULL)' is preferred - if you
strive for clarity that is.


August
 
E

Eric Sosman

arnuld said:
I thought it was a matter of style but you reacted like if OP has
violated ANSI standard.

Onay, Iyay eactedray ootay ayay illysay otivationmay.
 
G

Guest

| Eric Sosman wrote:
|> Keith Thompson wrote:
| [...]
|>> You can do it with no change in semantics. I wouldn't do it
|>> myself; I find
|>> if (pointer != NULL)
|>> clearer than
|>> if (!pointer)
|>
|> Not only clearer than, but opposite to.
|>
|
| Illustrates clearly why `if (pointer != NULL)' is preferred - if you
| strive for clarity that is.

I find them equally clear. But then, I'm not a beginner with C.
 
G

Guest

|> 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 buys clarity. I use NULL for a null pointer constant for the
| same reason I use 0.0 for a floating-point constant or '\0' for
| a character constant. I could use 0 in all these cases, and rely
| with complete confidence on the compiler to do the right implicit
| conversion (well, in most cases). But I'm not just communicating
| with the compiler. I'd be happier if the language had a keyword
| that specifically represents a null pointer constant, but since it
| doesn't NULL will do.

While I do avoid NULL because I don't really see a need to have it in
test expressions, I most certainly do avoid 0 because it's misleading.


| C's use of 0 for null pointer constants is, quite frankly, a bit
| of an ugly hack.

I would agree with this.


| Yes, it actually is a null pointer constant. The standard's
| definition of the term doesn't require it to be converted to a pointer
| type; it says that it yields a null pointer *if* it's converted to a
| pointer type. But yes, the fact that it's a null pointer constant
| isn't helpful in this case. So you have to remember to write
| (void*)NULL. (And how often do you pass a null pointer constant to
| printf anyway?)

Let me count the ways: NULL!=NULL

That's not counting use of NULL in macros invokations. Even then it is
likely to be less than: NULL==NULL
 
E

Eric Sosman

| Eric Sosman wrote:
|> Keith Thompson wrote:
| [...]
|>> You can do it with no change in semantics. I wouldn't do it
|>> myself; I find
|>> if (pointer != NULL)
|>> clearer than
|>> if (!pointer)
|>
|> Not only clearer than, but opposite to.
|>
|
| Illustrates clearly why `if (pointer != NULL)' is preferred - if you
| strive for clarity that is.

I find them equally clear. But then, I'm not a beginner with C.

And neither is anyone who will read your code?

Source code is written for two audiences: compilers and
people. The latter are the more important.
 
K

Kaz Kylheku

C's use of 0 for null pointer constants is, quite frankly, a bit
of an ugly hack.

The use of variations on 0 for a special value in different domains comes from
mathematics. For empty sets we have the slashed circle. Null vectors can be
written as variations on a zero; null matrices ditto.

http://en.wikipedia.org/wiki/Null_vector
http://en.wikipedia.org/wiki/Empty_set
http://en.wikipedia.org/wiki/Zero_matrix

The best notation for boolean algebra uses 0 for false and 1 for true;
or looks like addition, x + y, and and looks like multiplication: xy.

From mathematics, we should be accustomed to the idea that a round glyph
does not always just represent the zero on the real number line.
 
K

Kaz Kylheku

While I do avoid NULL because I don't really see a need to have it in
test expressions, I most certainly do avoid 0 because it's misleading.

It's misleading for amateur programmers who only learned about NULL,
and never bothered to inquire how NULL actually works.
 
K

Kaz Kylheku

Eric said:
Keith Thompson wrote: [...]
You can do it with no change in semantics. I wouldn't do it
myself; I find
if (pointer != NULL)
clearer than
if (!pointer)

Not only clearer than, but opposite to.

Illustrates clearly why `if (pointer != NULL)' is preferred - if you

How does it illustrate? Which of two the two mismatched expressions is
the one which was misunderstood to produce the other?
strive for clarity that is.

``If not pointer ...'' is perfectly clear.
 
K

Kaz Kylheku

(e-mail address removed) said:
|> Keith Thompson wrote:
| [...]
|>> You can do it with no change in semantics. I wouldn't do it
|>> myself; I find
|>> if (pointer != NULL)
|>> clearer than
|>> if (!pointer)
|>
|> Not only clearer than, but opposite to.
|>
|
| Illustrates clearly why `if (pointer != NULL)' is preferred - if
| you strive for clarity that is.

I find them equally clear. But then, I'm not a beginner with C.

Neither is Keith Thompson, but he managed to get it wrong. (No
reflection on Keith, by the way - everyone makes mistakes.)

Which did he get wrong? Translating if (!pointer) to if (pointer != NULL), or
vice versa? Was the error in the analysis of one or the synthesis of the other?
 
K

Kaz Kylheku

| Eric Sosman wrote:
|> Keith Thompson wrote:
| [...]
|>> You can do it with no change in semantics. I wouldn't do it
|>> myself; I find
|>> if (pointer != NULL)
|>> clearer than
|>> if (!pointer)
|>
|> Not only clearer than, but opposite to.
|>
|
| Illustrates clearly why `if (pointer != NULL)' is preferred - if you
| strive for clarity that is.

I find them equally clear. But then, I'm not a beginner with C.

And neither is anyone who will read your code?

Source code is written for two audiences: compilers and
people. The latter are the more important.

There is no reason to consider audiences who have more than, say, three to five
years less experience than you.

Hey, you know, let's ask Honda to make a car designed to be taken apart by
amateurs with no experience in car mechanics, using Walmart tools.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top