lint, pointers, 0 (what else?)

Guy Harris guy at rlgvax.UUCP
Thu Feb 7 04:27:24 AEST 1985


> (void) is an operation.  Performing it when it is called for
> should be no problem; apart from printf()/putc()/strcpy(),
> one usually SHOULD test the return value of most functions.

Even in the first two cases, it can be useful to test the return
value, so that you can tell when a write fails (and let the poor user
know that they've run out of space, or tried writing to a bad block,
before the "fclose"; the reason 4.xBSD blasts the "out of space" messages
to the user's terminal is probably that so few UNIX programs bother to
check for the success of "write"s).  "putc" is a nuisance, because
you don't want to check on every "putc", just on those that actually
write to the disk.  I've cooked up "ifgetc" and "ifputc" macros that
make this possible (the syntax is a bit ugly, but that's life).
Unfortunately, they're based on the "getc" and "putc" macros from "stdio.h",
and as such are protected by the terms of the UNIX license (and won't work
on different implementations of the Standard I/O library anyway),
but the trick is to do something like

	if (there's room(for putc)/data(for getc) in the buffer)
		put it there/get it from there;
	else if (flush(for putc)/fill(for getc)) fails

and write code like

	for (;;) {
		c = generate_character();
		ifputc(c, stdout) {
			perror("writing to stdout");
			done(1);
		}
	}

Also, another point on type-correctness: even on a Motorola 68000
implementation with 32-bit "int"s, you can lose if you don't declare
functions which return pointers.  See the article in the Dallas USENIX
proceedings by the people from Motorola on the System V microport.
The AT&T compiler (and, I'm told, the Sun compiler), put the return
value of pointer-valued functions in A0 - NOT in D0.  As such, if you don't
declare "malloc" as returning "char *", its caller will expect the return
value to be in D0 and will get whatever junk was there last.

This is NOT (1000 times NOT) a valid reason to putting the return value in D0.
It IS a valid reason for running your code through "lint".  C implementations
should not be governed by the problems of existing nonportable code; "lint"
(as many of us are getting tired of saying) can be used to catch those quite
nicely.

Lots of us have no trouble using "lint".  Lots of us have no trouble
declaring functions and putting casts in front of NULL, or in front of
functions whose return value we're ignoring.  It's a pain to use your turn
signal before turning - as evidenced by the number of people who don't do
it - but it's worth doing.  Trust me, it's worth doing.  The same applies
for trying to write type-correct code.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy



More information about the Comp.lang.c mailing list