Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84 SMI; site sun.uucp Path: utzoo!watmath!clyde!burl!ulysses!ucbvax!decvax!decwrl!sun!guy From: guy@sun.uucp (Guy Harris) Newsgroups: net.lang.c Subject: Re: how has C bitten you? Message-ID: <2702@sun.uucp> Date: Sat, 24-Aug-85 18:43:37 EDT Article-I.D.: sun.2702 Posted: Sat Aug 24 18:43:37 1985 Date-Received: Tue, 27-Aug-85 01:19:25 EDT References: <228@investor.UUCP> <132@mcgill-vision.UUCP> Organization: Sun Microsystems, Inc. Lines: 62 > [ ... ] > > 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 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