C style

Krzysztof Kozminski kk at duke.UUCP
Sun Oct 6 09:08:31 AEST 1985

In article <2848 at sun.uucp> Guy Harris writes (quoting somebody else, but in 
apparent support of this other person's critique of yet somebody else):
>> > For Heaven's sake, the big problem with this code is that the conditional
>> > is quite unreadable in in-line code like this.  I'd prefer
>> >	          while (illegal (ch = getch()))
>> > (where "illegal" is defined as a function testing its character argument). 

>> It may enhance readability, but it's not worthwhile.  You've just managed
>> to add a context switch per *character*.  Now, imagine what that's going to
>> do to a program like spell.

>Yes.  The System V "fgrep" uses a subroutine to do character comparisons.  The
>4.2BSD version uses a macro instead. The 4.2BSD version is substantially faster

Uh, aren't you exagerrating a little with all this speed optimization? How many
people use spell or fgrep on input that is hand-typed in real time? Wasn't it
*obvious* from the original article that the code was meant to deal with a live
human on the input end and *not* to read from a file?  Just to remind, this was
something to the effect of:

            while (illegal (ch = getch()))
		make_noise_and_protest_loudly(); /* I.e., putchar(BELL) */

I wish I could type fast enough to see any performance degradation from the
function call overhead in this situation :-)

If I wanted to do a *really fast* I/O with checking if input characters are
legal or not, and unless the set of illegal characters had nice properties
(like <32 or having some particular bit set or something) I'd trade off space
for speed, and do:

#define fast_access char /* or int, depending on the addressability and
		            comaparison speed considerations */
#if EOF != -1
something to call the attention of whoever is going to port this to elsewhere
(portability problems with the "257" below could be resolved analogously).
fast_access illegal[257];    /* Initialized to evaluate TRUE for illegal and
				FALSE for legal characters. */
#define ILLEGAL(a)	( illegal [1+(a)] )	/* Lots of comments why this */

	while ( ILLEGAL(ch=getchar()) )
	   { complain_in_some_way }

Fast, readable, no problems with side effects in macro substitution, either.
And you can change the illegal set dynamically.

Now if I *really* cared about speed ...  I'd rewrite getchar, too, to avoid the
addition.  Or experiment with:

#define ILLEGAL(a) ((illegal+1)[a])	/* Lots of comments what is this
					   expected to be */

which should avoid run-time addition.  Or I'd write this in assembler.  Or
perhaps design a custom processor :-)

More information about the Comp.lang.c mailing list