Comparing pointers to NULL

C

Chris Dollin

J. F. Lemaire said:
I know you were being facetious, but the above paragraph is
syntactically incorrect,

Chapter and verse?

--
"Common concerns such as property damage and wholesale Pintsize
destruction are of no concern to the king!" /Questionable Content/

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England
 
E

Eric Sosman

Nobody said:
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. [...]

Then you should go ahead and use them. If you find them
clearer, they're clearer, and clarity is in the something of
the what-not.

But *don't* choose one style over another merely because
it makes source code insignificantly shorter! That's what I
mocked in Charlie Zender's original post: Not the use of
`if (pointer)', but his motivation for wanting to use it.

Long, long ago I knew a programmer whose idea of optimizing
code was minimizing his keypunching time (I said "long, long
ago," right?). He used one- and two-character variable and
subroutine names, the absolute minimum of white space demanded
by the language at hand, and of course no space whatsoever on
comments. He was shockingly talented, but because his code
was maintainable only at great effort/expense, I'd have to say
he was not a good programmer: The artifacts he created had
short useful lifetimes. Maintaining his code was a rip-and-redo
proposition.

Charlie: Don't be another Glenn.
 
N

Nick Keighley

     Long, long ago I knew a programmer whose idea of optimizing
code was minimizing his keypunching time (I said "long, long
ago," right?).  He used one- and two-character variable and
subroutine names, the absolute minimum of white space demanded
by the language at hand, and of course no space whatsoever on
comments.  He was shockingly talented, but because his code
was maintainable only at great effort/expense, I'd have to say
he was not a good programmer: The artifacts he created had
short useful lifetimes.  Maintaining his code was a rip-and-redo
proposition.

handy people if you want something banged out quickly.
Ah yes we can call that library from C.
Now we need to real programmer to write a proper
library.

The guy I knew wrote code incredibly quickly.
He'd parse strings with a mind watering somme of pointer
arithmetic using hard coded values. If the string format changed
he'd re-write the code.

He also wrote an emulator for DEC's SOS editor in TPU
(DEC's, then, new shiny language for writing editors).
I said "cool! Can I have the source?"
<pause>
"source? why would you want the source? I've saved the binary"
 
J

James Kuyper

Eric Sosman wrote:
....
Long, long ago I knew a programmer whose idea of optimizing
code was minimizing his keypunching time (I said "long, long
ago," right?). He used one- and two-character variable and
subroutine names, the absolute minimum of white space demanded
by the language at hand, and of course no space whatsoever on
comments.

When I was using a keypunch to create my programs (in FORTRAN I), I
followed similar measures, for much the same reason. My error rate was
appallingly high, and every card completed as intended was precious.
Even a card that was completed incorrectly was sometimes valuable: if I
made a typo on the first use of an identifier, I would sometimes make
the typo the new "correct" name of the identifier. I deliberately
designed my programs so I could re-use individual lines from previous
assignments, just to avoid having to type a new line, and I also
deliberately designed them to increase the likelihood of being able to
reuse statements in later assignments.

I was fully aware of the problems associated with such strategies, and I
would never use such an approach in code that was intended for shared
use, or even for long term use just by me - it was just an emergency
measure that made it feasible for me to complete my homework assignments
on time. Programming was easy - keypunching was the bottleneck. I was
enormously relieved the first time I had access to a system that allowed
me to use a text processor to write my code.
 
K

Keith Thompson

| (e-mail address removed) writes: [...]
|> 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.

Do you think that 0[pointer] *should* be used in serious code?
 
K

Kaz Kylheku

| (e-mail address removed) writes: [...]
|> 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.

Do you think that 0[pointer] *should* be used in serious code?

I can make an argument for doing it but I could never bring myself to
actually do it. The objective would be to provide notation for a certain
kind of data organization that is no directly expressible in C.

0[ptr] is a silly strawman. See, the square brackets for indexing are
known and used outside of C, but their commutativity is a C peculiarity.

Using 0 for more than one kind of null is not a C quirk.

In mathematics notations there are variations on 0 which denote null vectors,
null matrices, null sets and boolean false.

So for instance p /= 0 is perfectly understood when p is a vector or matrix.

The one valid point against 0 is that the null pointer does not behave like an
additive identity element in the domain of pointers; the integer zero does
of sets (taking union to be addition).
for (employee = first_employee; employee <= last_employee; employee++) {
if (employee[citizenship] != "USA") {
/* Do stuff */
}
}

it might look more natural.

This is not a recommendation. :)

Actually, this is is very useful. Suppose there is a lot more nesting
in a data structure which, using pointers, would be traversed like this

a->b->c->d

but is implemented using array indices, so that b[a] is an integer,
which we then use to index into c[], etc:

d[c[b[a]]]

Nested too much and flipped right to left. Commutativity to the
rescue:

a[c][d]

That /needs/ no recommendation. :)
 
G

Guest

| But *don't* choose one style over another merely because
| it makes source code insignificantly shorter! That's what I
| mocked in Charlie Zender's original post: Not the use of
| `if (pointer)', but his motivation for wanting to use it.

Shortness == clarity. Just to make the whole file shorter is nonsense.
But to make one line shorter so it is easier to read, or even fits on a
line without overlap, that's clarity (although if it is close to wrapping
there may be other issues impacting clarity).


| Long, long ago I knew a programmer whose idea of optimizing
| code was minimizing his keypunching time (I said "long, long
| ago," right?). He used one- and two-character variable and
| subroutine names, the absolute minimum of white space demanded
| by the language at hand, and of course no space whatsoever on
| comments. He was shockingly talented, but because his code
| was maintainable only at great effort/expense, I'd have to say
| he was not a good programmer: The artifacts he created had
| short useful lifetimes. Maintaining his code was a rip-and-redo
| proposition.

Ye, I Ha to ag th us tw le va na ma th mu ha to re.
 
G

Guest

| (e-mail address removed) writes:
|> | (e-mail address removed) writes:
| [...]
|> |> 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.
|
| Do you think that 0[pointer] *should* be used in serious code?

No. I think 0[pointer] *can* be used ... e.g. not prohibited.

I can read 0[pointer] in code just fine. I don't have to stop and think
about it at all. I might not even notice that form was in some code I
might read. Other aspects of other people's code I find harder to read
than this.

Had I designed the language from the beginning, I would have used the syntax
of [pointer] for all pointer dereference (e.g. leave out the 0). This does
not create any syntax ambiguity. I even used this syntax to index variable
name space in a BASIC language interpreter I wrote in college. If given a
string expression inside [] not used to index an array, it would index the
top of the variable namespace. I would have no qualms about using it for a
purpose like that in the future if I find myself designing a language, or
implementing one that I can extend (assuming it is compatible). The thing
of interest here is that the run time models of these other languages have
live string indexed namespaces for variables, while C has raw virtual memory
access. So if you think of 0 as being a reference to all of memory itself,
then 0[pointer] is just like using the pointer value to index memory.

BTW, the [pointer] syntax could be added as an extension to standard C now,
an causes no syntax conflicts I can see.
 
A

Alexander Bartolich

[...]
I can read 0[pointer] in code just fine. I don't have to stop and think
about it at all. I might not even notice that form was in some code I
might read. Other aspects of other people's code I find harder to read
than this.

Call me lame, but I do have to stop and think about it. I naturally
expect an identifier the left of the square bracket. So I would go
search for an array or pointer called O, i.e. uppercase o.
 
G

Guest

| (e-mail address removed) wrote:
|> [...]
|> I can read 0[pointer] in code just fine. I don't have to stop and think
|> about it at all. I might not even notice that form was in some code I
|> might read. Other aspects of other people's code I find harder to read
|> than this.
|
| Call me lame, but I do have to stop and think about it. I naturally
| expect an identifier the left of the square bracket. So I would go
| search for an array or pointer called O, i.e. uppercase o.

Perhaps it is because I have used something akin to that before. It just
makes sense to me, semantically without analyzing it in terms of the
commutative property.
 
E

Eric Sosman

| But *don't* choose one style over another merely because
| it makes source code insignificantly shorter! That's what I
| mocked in Charlie Zender's original post: Not the use of
| `if (pointer)', but his motivation for wanting to use it.

Shortness == clarity.

Balderdash. (Oh, sorry: "Bull.")

For a shining counter-example, see Ben Pfaff's signature.
 
B

Bartosz Wroblewski

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

0[pointer]

Thank you for an enlightening moment here - this is the most illustrative
pointer trivia I've seen. I would argue that realising how it works makes
one a better C programmer. ;-)
 
G

Guest

| On Sun, 09 Aug 2009 07:59:22 +0000, phil-news-nospam wrote:
|>
|> Will that education include that the following is valid (and what it
|> does)?
|>
|> 0[pointer]
|
| Thank you for an enlightening moment here - this is the most illustrative
| pointer trivia I've seen. I would argue that realising how it works makes
| one a better C programmer. ;-)

Now go figure out why it is that you cannot use this form to express the
definition of a variable, such as:

double *pointer; /* OK */
/* vs */
double 0[pointer]; /* wrong */

Figure that one out and you've learned even more.
 
B

Bartosz Wroblewski

double *pointer; /* OK */
/* vs */
double 0[pointer]; /* wrong */

Figure that one out and you've learned even more.

I'd wager that this is because according to C's syntax, 0 is parsed as an
identifier here. In addition to that, that bit actually declares an array
of size /pointer/ - so /pointer/ would have to be a pre-defined constant.

Oh - and commutativity or not, /double pointer[0]/ wouldn't work. Neither
would /double pointer[1]/. I don't see much to "figure out" here, really.
 
K

Keith Thompson

Bartosz Wroblewski said:
double *pointer; /* OK */
/* vs */
double 0[pointer]; /* wrong */

Figure that one out and you've learned even more.

I'd wager that this is because according to C's syntax, 0 is parsed as an
identifier here. In addition to that, that bit actually declares an array
of size /pointer/ - so /pointer/ would have to be a pre-defined constant.

No, 0 is never parsed as an identifier; it's always an integer
constant.

When the compiler analyzes the line it generates a sequence of tokens:

double 0 [ pointer ] ;

There is no rule in the grammar that can match that particular
sequence of tokens, so the compiler reports a syntax error. (gcc's
error message is "error: expected identifier or `(' before numeric
constant"; it recognizes the impossibility of a match as soon as it
sees the 0.)
Oh - and commutativity or not, /double pointer[0]/ wouldn't work. Neither
would /double pointer[1]/. I don't see much to "figure out" here, really.

Agreed. Declarations mirror usage to some extent, but not perfectly.
 
B

Bartosz Wroblewski

No, 0 is never parsed as an identifier; it's always an integer constant.

When the compiler analyzes the line it generates a sequence of tokens:

double 0 [ pointer ] ;

There is no rule in the grammar that can match that particular sequence
of tokens, so the compiler reports a syntax error. (gcc's error message
is "error: expected identifier or `(' before numeric constant"; it
recognizes the impossibility of a match as soon as it sees the 0.)

Right, I was rather unclear. What I meant was that the compiler tries to
find an identifier and fails horribly. Thanks for the clear explanation,
though.
 

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

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,112
Latest member
VinayKumar Nevatia
Top