ok@edai.UUCP (Richard O'Keefe) (03/10/84)
One kind net.lang.c reader pointed out that Lint was JUSTIFIED in its complaints about my passing NULL to functions expecting a pointer argument. What I hadn't realise was that stdio.h defines #define NULL 0 (I thought it was (char*)0.) Now I know that there is no hope of ever running the program I've been struggling with on a 16- bit machine, the question is will it run on a machine with 32- bit pointers but int=16 bits. So I've changed my header file, it now starts #include <stdio.h> #undef NULL #define NULL 0L This works fine on the VAX, but then so did NULL=0. Can any reader with a ptr=32&int=16 C compiler tell me if this is ok for such compilers? PS: my request for an ALIGNOK directive to Lint had nothing to do with *this* problem.
gwyn@brl-vgr.ARPA (Doug Gwyn ) (03/12/84)
NO NO NO You MUST cast the 0 to the proper pointer type when passing it as an actual argument to a function: foo( (char *)0 ); for example. There is no other way of guaranteeing that the function gets a pointer of the proper type.
tjt@kobold.UUCP (03/12/84)
Using: #include <stdio.h> #undef NULL #define NULL 0L will fail on a machine with 16 bit pointers, 16 bit int's but 32-bit longs (the pdp-11, for example). On the pdp-11, defining NULL as 0L will cause two words to be pushed on the stack for as a function argument while the called routine will only be expecting one word for that argument. As has been pointed out too many times to count, it is impossible to define a generic null pointer in C: you have to cast 0 to the pointer type when passing it as an argument. You can do this by including the type cast in each use, or #define a null pointer for each pointer type you use. -- Tom Teixeira, Massachusetts Computer Corporation. Westford MA ...!{ihnp4,harpo,decvax}!masscomp!tjt (617) 692-6200 x275
guy@rlgvax.UUCP (Guy Harris) (03/13/84)
> #include <stdio.h> > #undef NULL > #define NULL 0L > This works fine on the VAX, but then so did NULL=0. Can any > reader with a ptr=32&int=16 C compiler tell me if this is ok > for such compilers? Yes, it works on our compiler. However, "lint" will *still* yell at you (it isn't complaining about the size of the object, it's complaining about its type), it means the code won't work on a 16-bit machine (even if it would fit) nor will it work on a machine where (to pick a possibly strange example) pointers and "int"s are 32 bits while "long"s are 64 bits, and it won't work on a machine where the representation of a null pointer isn't a string of all zero bits. Why not just run the code through "lint" and read and heed its warnings? Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy
tim@unc.UUCP (Tim Maroney) (03/14/84)
This reminds me -- another small change that the ANSI Standard committee might want to make in C is to make NULL be a real synatctic object, so that we don't have to do dumb-looking (and usually forgotten) things like: foo( (char *)NULL ); After all, the use of NULL in software has become part of the de facto C standard. -- Tim Maroney, University of North Carolina at Chapel Hill mcnc!unc!tim (USENET), tim.unc@csnet-relay (ARPA) All opinions expressed herein are completely my own, so don't go assuming that anyone else at UNC feels the same way.
msc@qubix.UUCP (Mark Callow) (03/14/84)
The situation as succintly as I can put it is: 1) The C language definition (K&R) says that the *symbol* '0' may be used to represent a null pointer. 2) The compiler therefore has to identify places where '0' is being used as a null pointer (for example by identfying assignments to or comparisons with pointers) and it has to *replace it with* the actual value of a null pointer for the particular machine and the data type being pointed to. 3) Given that there is no requirement (and no way) to inform the compiler of the types (or number) of arguments to an external function the compiler can't know that some argument to your function is a pointer. In the case of func( 0 ); therefore, the compiler can't intuit whether '0' is being used as a null pointer or in its more common usage as the symbol for the arithmetic value 0. 4) The compiler assumes the more common usage so if the argument to *func* is actually a pointer you *must* give an explicit cast to the correct type of pointer. For example you must say func( (char *)0 ); -- From the Tardis of Mark Callow msc@qubix.UUCP, decwrl!qubix!msc@Berkeley.ARPA ...{decvax,ucbvax,ihnp4}!decwrl!qubix!msc, ...{ittvax,amd70}!qubix!msc
hom@hocda.UUCP (H.MORRIS) (03/16/84)
A "real" NULL such that one can say foo(NULL) instead of foo((char *)NULL) with perfect assurance implies that while compiling the line foo(NULL) the cc knows something about the arguments declared for the function foo. That implies in turn that either cc snoops around for the file containing the declaration of foo - which gives you a language with a radically different philosophy from C, or else within the file containing `foo(NULL)' there is a declaration of the form: return-type foo( (char *)); instead of what is currently allowed: return-type foo(); (the former describes foo's arguments; the latter doesn't). I heard somewhere that this is being considered. I am not passionate about whether function definitions which describe the argument type are a good thing. I feel strongly that they should be optional so as to allow functions which take variable argument lists like printf. But just to point out that without such a construct, you can't have foo(NULL) work always on all machines when argument to foo is a pointer. Hal MOrris ...hocad!hom