Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site duke.UUCP Path: utzoo!linus!decvax!mcnc!duke!kk From: kk@duke.UUCP (Krzysztof Kozminski) Newsgroups: net.lang.c Subject: Re: C style Message-ID: <6421@duke.UUCP> Date: Sat, 5-Oct-85 19:08:31 EDT Article-I.D.: duke.6421 Posted: Sat Oct 5 19:08:31 1985 Date-Received: Wed, 9-Oct-85 04:00:40 EDT References: <1556@brl-tgr.ARPA> <139200011@uiucdcsb> <309@seismo.CSS.GOV> <2848@sun.uucp> Reply-To: kk@duke.UUCP (Krzysztof Kozminski) Organization: Duke University Lines: 55 Summary: In article <2848@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). #endif 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 :-)