Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!batcomputer!itsgw!steinmetz!uunet!auspex!guy From: guy@auspex.UUCP (Guy Harris) Newsgroups: comp.lang.c Subject: Re: use of NULL Keywords: NULL zero 0 C Microsoft Message-ID: <1063@auspex.UUCP> Date: 24 Feb 89 20:38:34 GMT References: <1167@unisec.usi.com. <5312@turnkey.TCC.COM. <9582@smoke.BRL.MIL. <399@twwells.uucp: <973@optilink.UUCP> <9684@smoke.BRL.MIL> <20928@shemp.CS.UCLA.EDU> Reply-To: guy@auspex.UUCP (Guy Harris) Organization: Auspex Systems, Santa Clara Lines: 45 >Excuse me for a probably naive question that I've had since following the >discussion of passing NULL to functions: Why doesn't the C standard >treat NULL or 0 (a static/constant NULL or 0, i.e. indicated at compile time) >passed to a function that has a pointer value in the function prototype >as a special case and do the cast implicitly? It does. (It's not really a "special case"; conversions in calls to functions with a prototype in scope are just like other conversions - at least according to the May 13, 1988 draft, which says the conversions are performed "as if by assignment".) However: 1) not all compilers *support* function prototypes, so unless you *never* expect to compile your code in an environment where the appropriate prototypes are not in scope, it's probably wise to put the explicit casts in anyway. 2) not all environments put the prototypes in the appropriate include files; see 1). 3) actual arguments that aren't matched by formal arguments in the prototype (i.e., if the prototype has a "..." in it) obviously can be converted only with the "default argument promotions", which obviously doesn't include converting 0 to a null pointer of the appropriate type. Doug was probably referring to one or more of those cases when he said: "Use of uncast NULL as an argument to a function is never correct usage ..." "Never" might, admittedly, be a little strong, if you take "correct" to mean "proper according to the pANS"; if you have extern void foo(char *ptr); in scope, a call foo(0); /* or foo(NULL); */ is correct - as long as you know for sure that in *every* environment in which this code will be compiled, the prototype in question will be in scope when "foo" is called.