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