Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!caip!lll-crg!lll-lcc!pyramid!decwrl!sun!guy From: guy@sun.uucp (Guy Harris) Newsgroups: net.micro.amiga,net.lang.c Subject: Re: printf() code size using Astartup.obj and AMIGA.LIB only Message-ID: <4907@sun.uucp> Date: Wed, 9-Jul-86 13:52:45 EDT Article-I.D.: sun.4907 Posted: Wed Jul 9 13:52:45 1986 Date-Received: Fri, 11-Jul-86 06:30:38 EDT References: <8606270438.AA07486@pavepaws> <426@oscvax.UUCP> <84@unisoft.UUCP> <566@3comvax.UUCP> <1385@well.UUCP> <951@jade.BERKELEY.EDU> Organization: Sun Microsystems, Inc. Lines: 54 Xref: watmath net.micro.amiga:3911 net.lang.c:9802 > > It never fails to amaze me just how many people do this: > > if (foo == NULL) { ... } > > or: > > if (foo == 0) { ... } > [instead of...] > > if (!foo) { ... } > > Well, I wrote it the way you think people ought to for 8 years before > changing to coding the test explicitly. I changed because the (!foo) > notation is less readable than the (foo == 0) notation. Amen. The three constructs given have exactly the same meaning in C (yes, wait for the explanation, it's true) and any good compiler will produce exactly the same code for them. However, "!foo" is suggestive of testing for the falsity of a Boolean (yes, I know C doesn't have a formal Boolean type, but that's the proper way to think of something with values meaning "true" and "false"), while "foo == NULL" is suggestive of testing whether a pointer is null or not, and "foo == 0" is suggestive of testing whether an integral value is zero or not. > Also, if foo is a pointer type, the test (!foo) is wrong. NULL doesn't > have to be zero. Oh, yes it does. A null pointer need not have a bit pattern consisting of all zeroes. However, the value of a null pointer is constructed in C by converting the integral constant 0 to a pointer type. In the construct "foo == 0", the LHS is a pointer, so the compiler knows enough to convert the "0" on the RHS to a pointer of the same type, hence a null pointer of the appropriate type. (No, I won't cite the K&R/ANSI C draft which says this; seek and ye shall find.) As such, NULL should be #defined as 0 - NOT "(char *)0", because that causes the compiler to get annoyed when you compare an "int *" against NULL, since you're comparing two different kinds of pointers. > > The reason the compiler is exhibiting the behavior you describe is > >because you told it to. You are asking the compiler to compare an unsigned > >byte to the literal value of NULL. Which should always be 0. As such, in the example given, if (var == NULL) ... is identical to if (var == 0) ... and should generate the same code; as the author of the response to the above comment points out, there is NO reason to extend a 1-byte variable "var" to 4 bytes when doing this. -- Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com (or guy@sun.arpa)