Comparing pointers to NULL

K

Keith Thompson

Richard Heathfield said:
Kaz Kylheku said:
(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?

Well, only Keith knows that.

You overestimate me.

(Thanks for that.)
 
E

Eric Sosman

Kaz said:
| 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.

Then I will be writing code for what I believe is a small
minority of programmers. I was first paid for code in 1966;
can I safely ignore all programmers who didn't know their craft
by the time Jimmy Carter took office? I was first paid for C
code in 1978; can I just forget about those who hadn't learned
C by the end of Ronald Reagan's first term?

By one of *those* coincidences, in another newsgroup right
now there's a thread of epigrams and sayings about programming.
Somebody contributed this quotation from an author whose books
you have probably studied:

“Let us change our traditional attitude to the
construction of programs. Instead of imagining that
our main task is to instruct a computer what to do,
let us concentrate rather on explaining to human
beings what we want a computer to do.”
-- Donald Knuth
 
K

Keith Thompson

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

The solution is to educate those programmers.

My assumption is that whoever reads my code knows the language. Given
that assumption, I still think that
if (foo != NULL)
reads better than either
if (foo != 0)
or
if (foo)
even to a reader who's perfectly well aware that all three are
equivalent. For one thing, it's a small reminder that foo is a
pointer (or at least that the author thought it was a pointer).
Reading code is about building a mental model of what the code is
doing; small unobtrusive hints here and there can make that easier.

One drawback, of course, is that, if NULL is defined as 0 (as
it often is), the compiler won't diagnose attempts to use it in a
non-pointer context. I've seen code that checked for null characters
by comparing against NULL; the code compiled and worked.

NULL is easy to misuse if you don't know how to use it. The same
is true of any feature of the language.

One could almost argue that *avoiding* NULL is a crutch for
programmers who don't quite understand how to use it. Not quite,
but almost.
 
P

Phil Carmody

Kaz Kylheku said:
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?

It illustrates clearly that _one_ of the two should be prefered.
``If not pointer ...'' is perfectly clear.

Agreed, it's what I automatically use myself. But in a file that
had some NULL comparisons, I'd want all NULL comparisons.

Phil
 
O

Old Wolf

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.

I'm not sure if that's a great analogy, amateurs
with no experience *can* take a car apart, using
tools from the local discount tool place.

For older cars most parts of them are pretty
straightforward to pull apart and see how they work.
 
G

Guest

| (e-mail address removed) said:
|
|> On Sat, 08 Aug 2009 13:12:19 +0200 August Karlstrom
|> | 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.
|
| Neither is Keith Thompson, but he managed to get it wrong. (No
| reflection on Keith, by the way - everyone makes mistakes.)

Well, at least he didn't do:

if (pointer == NOTNULL)

:)

If we want to make the code look more like prose or documention, we could
play around with macros

#define pointer_is_null(p) ((p)==NULL)
#define pointer_is_not_nul(p) ((p)!-NULL)

OR

#define pointer_is_null(p) (!(p))
#define pointer_is_not_nul(p) (!!(p))

depending on preferences. But then you have code that look a bit less like
C which may or may not be a good thing.

if (pointer_is_null(pointer))
 
G

Guest

|>> 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.
|
| The solution is to educate those programmers.

Will that education include that the following is valid (and what it does)?

0[pointer]
 
K

Keith Thompson

|>> 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.
|
| The solution is to educate those programmers.

Will that education include that the following is valid (and what it does)?

0[pointer]

Yes, and yes, and in addition why it should never be used in serious
code.

One can be a decent C programmer without being aware that the []
operator is commutative, but any deep education in C is likely to
include that (fairly useless) fact.
 
P

Paul Hsieh

is
if(pointer != NULL) ...
always exactly equivalent to
if(pointer) ...
for all pointer types, e.g.,
int *pointer;
?

You have to include stdio.h or something like that to get the
definition of NULL and then you can't redefine it. Otherwise, the two
are equivalent.
i.e., can I safely avoid typing "!= NULL" to shorten my NULL-
comparisons?

You can, but that makes your code harder to maintain. It is rare to
change from a pointer type to another kind of type, so knowing what a
comparison means is usually more helpful than trying to save
horizontal text. (Keep in mind that your compiler will not produce any
different object code in either case.)
 
N

Nick Keighley

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

an odd attitude
 
N

Nick Keighley

My beef with NULL is that it is all caps, giving the keyword (because that's
what effectively it is) a visual emphasis that it shouldn't have. null or
nil would be fine, but it's too late to make that change now.

aren't the C++ people doing something like that in the new standard?
 
D

Don Bruder

"Malcolm McLean said:
My beef with NULL is that it is all caps, giving the keyword (because that's
what effectively it is) a visual emphasis that it shouldn't have. null or
nil would be fine, but it's too late to make that change now.

So, since visual emphasis is your concern here, what's so difficult
about the simple cure:

#define nil NULL

or

#define null NULL

or even both, quietly tucked away in some "boilerplate" header you
rarely, if ever, need to actually look at?

Presto - no need for new standards-wrangling, no broken code, zero
impact of any kind on anyone anywhere, except that now you're happy.

(Well, unless what makes you happy is finding something to nitpick and
bellyache about, of course...)
 
N

Nick Keighley

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


"Programs must be written for people to read,
and only incidentally for machines to execute."
— Harold Abelson
(Structure and Interpretation of Computer Programs)
 
N

Nick Keighley

So, since visual emphasis is your concern here, what's so difficult
about the simple cure:

#define nil NULL

or

#define null NULL

or even both, quietly tucked away in some "boilerplate" header you
rarely, if ever, need to actually look at?

Presto - no need for new standards-wrangling, no broken code, zero
impact of any kind on anyone anywhere, except that now you're happy.

(Well, unless what makes you happy is finding something to nitpick and
bellyache about, of course...)

It's a lower case macro. I know the standard has a few but I don't
have to like it. It isn't standard. I want a null reserved word.
You still have to have work arounds forthings like variadic
functions (this may be unavaoidable)
 
J

James Kuyper

Nick said:
aren't the C++ people doing something like that in the new standard?

Yes. The keyword nullptr is a pointer literal of type std::nullptr_t. It
counts as a null pointer constant. It can be converted to bool, giving a
value of 'false'. Unlike NULL or 0, it can be converted to an integer
type only under the same circumstances that (void*)0 could be so
converted; the fact that NULL is not so restricted is my biggest
objection to NULL.
 
O

osmium

Malcolm McLean said:
That's the Africar / car Ford designed for missionary and charitable
agencies in Latin America. A car with solid tyres, that was light enough
for the passengers to lift over a stream or out of a pothole, and that
could be serviced with minimal tools.

It also cost something like 2000 dollars.

Ford did it, then clamped down on the project in case too many people in
the United States bought it, undermining the traditional car market.

That sort of thinking is one reason why the US car industry is in such a
mess.

ISTM that such a car would have very high pollution and thus could not be
sold in the US, anyway. A lot of the complexity of a modern car is related
to the anti-pollution stuff.
 
N

Nobody

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

I beg to differ. I find if(pointer) and if(!pointer) entirely clear, and
preferable to explicit comparisons. Likewise for predicates which return
non-zero for true and zero for false.

Using if(pointer!=NULL) is using a negated test to a "negative" value,
which conspire to hide the fact that it's a positive test.

OTOH, for POSIX API return codes (zero for success, negative for failure)
I prefer if(func()==0) and if(func()<0) to be the most clear (or least
unclear; you can't avoid a negation when 0 means success).

At least it's not as bad as PIC assembler:

btfsc STATUS,Z
goto somewhere

"btfsc" = Bit-Test File (aka register), Skip if Clear.

So if the zero flag (negation) is clear (negation), skip (negation) the
following instruction. Also, the goto may itself be a negation (goto
skip_over_the_next_part), and the input might be negated (a pin attached
to a push button will normally be 0 when pressed, 1 otherwise). Oh, and
for subtraction, C(arry)==0 => borrow, C==1 => no borrow.
 
K

Kaz Kylheku

Using if(pointer!=NULL) is using a negated test to a "negative" value,
which conspire to hide the fact that it's a positive test.

What? ``x /= 0'' comes up often in mathematics.
 
K

Keith Thompson

Kaz Kylheku said:
What? ``x /= 0'' comes up often in mathematics.

Where "/=" is an ASCII representation of the mathematical not-equal
sign, not the C compound assignment operator (just in case anyone else
might be unclear on this point).
 
G

Guest

| (e-mail address removed) writes:
|> |>> 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.
|> |
|> | The solution is to educate those programmers.
|>
|> Will that education include that the following is valid (and what it does)?
|>
|> 0[pointer]
|
| Yes, and yes, and in addition why it should never be used in serious
| code.

I'm sure I'll disagree with it.
 

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,774
Messages
2,569,598
Members
45,144
Latest member
KetoBaseReviews
Top