[comp.lang.c] Use of NULL in UNIX & C

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