barber@rabbit1.UUCP (Steve Barber) (11/12/86)
I'm going to go out on a limb here, but it's a limb I'm comfortable on. The use of the identifier NULL, as defined by stdio.h in all UNIXes I've ever seen (v7, BSD4.[123], System III & V, Xenix, IN/ix, and many more obscure variants), by itself as any kind of pointer, is a non-portable usage and as such is incorrect for use in programs that are meant to be used on more than one implementation of "UNIX" (loosely defined) or in multiple memory models on those machines where this concept is relevant (e.g. almost anything with an Intel processor). When writing code, bite the bullet and type those extra 8 or so characters when using NULL as a pointer value: (char *) NULL, (int *) NULL, or whatever the type of the expression should be. People, this will save so much time in the long run and is the only general solution. Tricks with the preprocessor may work for some cases but not all, and I guarantee that more time will be wasted on these than could be spent typing in the casts to begin with. When porting code of unknown or dubious ancestry to a new architecture, one of the first things I do is to grep over the code for NULLs and fix up those that are not cast properly since it is such a common error. This check takes little time, and has a big payoff. Bugs introduced by these problems are almost always obscure. In summary: If using NULL in an expression whose result is something other than int, short, unsigned short, or unsigned int, always cast it. I realize that some may disagree with this position. Please do so by mail, as I think I can probably convince you of my position without a public flame war. In fact, if anyone sees any flaws in the above I'd love to hear about them. I have directed followups to net.lang.c as this is no longer really a UNIX issue. -- Steve Barber Rabbit Software Corp. ...!ihnp4!{cbmvax,cuuxb}!hutch!barber ...!psuvax1!burdvax!hutch!barber (215) 647-0440 7 Great Valley Parkway East Malvern PA 19355
jc@cdx39.UUCP (John Chambers) (12/05/86)
> Newsgroups: net.lang.c
[Gee, I wish people wouldn't redirect followups to non-existent newsgroups! :-]
This has been a constant hassle in porting code to 68000s,
because many C compilers give me 16-bit ints and 32-bit
pointers. One of the most common examples:
l = time(NULL);
gets a Segmentation Fault, because the NULL is #defined as
just 0, and only 16 bits of zeroes are stacked. The routine
fetches them plus 16 bits of garbage and tries to store the
clock value there.
In general, it might be a good idea to define a bunch of nulls:
#define NULLI ((int)0)
#define NULLL ((long)0)
#define NULLP ((char*)0)
#define NULLR ((real)0)
...
Now if there were only a way to ensure proper alignment in
printf() formats. I've heard a rumor that there's a version
of lint somewhere that has an option to check for this. The
2.11 news release bombed spectacularly here due to some printfs
like:
printf("... %x ... %s ...",p1,p2);
When I changed it to %lX it worked just fine.
--
John M Chambers Phone: 617/364-2000x7304
Email: ...{adelie,harvax,inmet,mcsbos,mit-eddie,mot[bos],rclex}!cdx39!{jc,news,root,usenet,uucp}
Smail: Codex Corporation; Mailstop C1-30; 20 Cabot Blvd; Mansfield MA 02048-1193