Path: utzoo!utgpu!water!watmath!clyde!bellcore!decvax!ucbvax!pasteur!ames!nrl-cmf!mailrus!umix!umich!palam!janc From: janc@palam (Jan Wolter) Newsgroups: comp.sources.bugs Subject: Re: pointer checking Summary: The real problems are elsewhere Keywords: 16 bits vs 32 bits Message-ID: <779@zippy.eecs.umich.edu> Date: 17 Feb 88 20:57:18 GMT References: <228@gandalf.littlei.UUCP> <1204@itm.UUCP> Sender: news@zippy.eecs.umich.edu Reply-To: janc@palam.eecs.umich.edu (Jan Wolter) Organization: University of Michigan EECS, Ann Arbor Lines: 53 UUCP-Path: palam!janc NULL is a pointer with an illegal value. In some architectures, the address 0 is a perfectly reasonable address, so it is concievabale that someone might set up a system with NULL defined as ((char *) -1), or some such. However, I've never heard of anyone doing that, and, in fact, it would be contrary to K&R's definition of C. Usually some other action is taken to assure that the memory at address 0 will not contain anything anyone will want to point to. Nevertheless, I think in terms of readiblity, if (ptr == NULL) is superior to if (!ptr) It makes what you are doing clearer, generates the same code, and might even prove more portable to some goofy machine. Doing a type cast like (ptr == (char *)NULL) shouldn't be necessary, since NULL should be defined as (char *)0. (Some 32-bit systems define NULL as 0, which just helps perpetuate the confusion between integers and pointers which Vax programmers seem to sufferer from). The real portability problems arise most commonly from people not declaring routines that return a pointer or an integer. It's common for people to use lseek() or malloc() without including: char *malloc(); long lseek(); This is sure to screw up any 16-bit system, an a very nasty and hard to debug way. I recommend that you explicitly declare anything who's returned value you are using, even if it returns an int. Defaults stink. Another common error is in the passing of arguments. For example, the man page on my Sun gives the function synopsis for execl() as: execl(name,arg0,arg1, ..., argn, 0) char *name, *arg0, *arg1, ..., *argn; which is dead wrong. That should be a NULL, not a 0. It's no wonder that this kind of error is made all the time. I wish enough compilers supported function prototyping so that people would actually start using it. It's astonishing the number of people who don't know the difference between NULL, 0L and 0. These two types of things account for 90% of all errors I encounter when porting software to systems with 16-bit integers. The rest are mainly using %d to print a long in a printf(), and assuming you can put 32-bit numbers in an int. These are comparitively scarce. Jan Wolter janc@crim.eecs.umich.edu