const, volatile, etc

Doug Gwyn gwyn at smoke.BRL.MIL
Sat Dec 3 18:39:51 AEST 1988


In article <10929 at ulysses.homer.nj.att.com> ggs at ulysses.homer.nj.att.com (Griff Smith) writes:
>Good start.  Now, what do I do about upgrading a million lines of old
>code to the new standard, and finding all the mis-declared variables.

You could do what I've had to do for each release of UNIX from AT&T:
Go through the entire goddamn source code and fix everything the hard
way.  I have a small list of things I look for that catch most poor
practices.  Here are some of them:
	char c;		// look for a following (c = getc())
	sig*		// signal handling is almost always wrong
	unlink(		// add check first for null filename pointer
	argv		// check argc first
	/*VARARGS*/	// usually doesn't use <varargs.h>
	error		// may need to be varargs-ized
	#if		// check that conditionalization is right
	u3b		// usually a 3B-only kludge instead of a fix
	gets(		// usually used unsafely
	strc..(		// often used unsafely
	scanf(		// often used wrong
	BUFSIZ		// usually indicates an unsafe assumption
	execl*(		// terminator usually needs cast
	unsigned	// sometimes mixed expressions need casts
		// look at EVERYthing that "lint -p" squawks about:
	read(		// buffer address usually needs cast
	write(		// buffer address usually needs cast
	malloc(		// declaration often missing
	lseek(		// declaration often missing
	time(		// declaration often missing
	exit(		// declaration often missing
	free(		// declaration often missing
	perror(		// declaration often missing
	return;		// often missing value
What I don't know is why AT&T didn't do all this a long time ago.
For the $80,000 or so we have to pay for a source license, it is
reasonable to expect good quality control to have been applied.

As to changes brought on by a new release of a C compiler, there
is no easy way to be sure what compiler-dependent assumptions
were made in existing code.  The specific problem you mentioned
concerning data shared with an asynchronous signal handler can
be searched for fairly readily by grepping for use of signal()
then hunting down the handlers and see just what they do (not
very much in most cases).  Add "volatile" to shared flags, and
consider using type sig_atomic_t for them (which you need to
typedef yourself for non-__STDC__).  UNIX PCCs have used a
variety of techniques to prevent hyperoptimization of accesses
to potential device registers in compiling device drivers.  For
example, one I know of knew what hardware addresses were used
for device registers and disabled such optimization for them.
Many device drivers are still critically dependent on the way
the code generator works, so they need to be reviewed EVERY
time the code generation changes.



More information about the Comp.lang.c mailing list