how has C bitten you?
Guy Harris
guy at sun.uucp
Sun Aug 25 08:43:37 AEST 1985
> [ ... ]
> > if(telno){ /* should be if(*telno) */
> [ ... ]
>
> > Print statements showed the telno was being handed to the routine,
> > but the if said nothing was there. Turns out, on my system, the
> > address of telno is NULL. I needed to check the contents not the
> > address!
>
> Gee....and I thought a zero pointer was guaranteed not to point to
> anything valid (K&R says this).
All valid implementations of C guarantee this. Obviously, the
implementation of C that this was done on is not valid. He should complain
to the vendor. (Yes, there have been such implementations; one well-known
chip maker's first UNIX release didn't put the necessary shim at data
location 0 on a separate I&D space program. They fixed it shortly
afterwards.)
> Or is NULL not a zero?! No, you are comparing to 0 not NULL.
If you compare a pointer against 0, the actual code compiled compares it
against a null pointer. NULL *is* 0, if you're talking from the standpoint
of "what does the '#define' in <stdio.h> and other places say":
/* @(#)stdio.h 1.2 85/01/21 SMI; from UCB 1.4 06/30/83 */
...
#define NULL 0
(and you'll find the same thing in V7, 4.2, 4.3, S3, S5, ...). In any
context where it is known to the compiler that something is supposed to be a
pointer to a specific data type, any zero that appears there is treated as a
null pointer of the type "pointer to that data type" (obviously, not a null
pointer to an object of that data type, since a null pointer can't point to
anything). These contexts include comparisons and assignments, so the two
assignments in
register struct frobozz *p;
p = 0;
p = (struct frobozz *)0;
are equivalent and the two comparisons in
if (p == 0)
foo();
if (p == (struct frobozz *)0)
foo();
are equivalent. Procedure calls, however, are not such a context, so the
two procedure calls in
bar(0);
bar((struct frobozz *)0);
are very definitely *not* equivalent. In ANSI Standard C, there is a syntax
to specify that "bar" takes an argument of type "struct frobozz *"; if you
declared "bar" in such a manner, the two procedure calls would be equivalent.
Guy Harris
More information about the Comp.lang.c
mailing list