tom (04/28/83)
Concerning recent query why #2 below does not accomplish the same as #1. 1) if ( ! ((*p >= '0' && *p <= '9') || (tolower(*p) >= 'a' && tolower(*p) <= 'f')) ) return(0); p++; 2) if ( ! ((*p >= '0' && *p <= '9') || (tolower(*p) >= 'a' && tolower(*p++) <= 'f')) ) return(0); It has to do with the proper evaluation of the logical OR(||) in #2. if "*p" is a digit, the first paranthesized test evaluates TRUE. Therefore, since the expression "TRUE OR x" is always TRUE, there is no reason to do the second parenthesized test. The result of the OR is TRUE, the NOT(!) is FALSE, so the entire test is FALSE and execution drops down to the next statment without ever doing the "p++". See pg 191 of "The C Programming Language": "Unlike |, || guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the value of the first operand is non-zero." It was then asked how to rewrite #1 or #2 to eliminate the separate "p++" statement of #1. Why the h--- bother? Isn't the code sufficiently difficult to read without hiding the incrementation? For efficiency? At best, avoiding the separate "p++" buys so little efficiency I doubt it could ever be measured. At worst, machines without an auto-post- decrement instruction might be slower if the increment were bundled into an earlier reference to "p". And then of course, there is the inefficiency of doing the "p++" immediately prior to returning, Also, I think any solution which eliminates the separate "p++" would also eliminate the logical optimization mentioned above -- namely all of the comparisons would be done even though the result is known part-way through, thus making it even less efficient. - Tom Beres {seismo, we13, mcnc}!rlgvax!tom
and (05/13/83)
In c-language, logical expressions are evaluated only enough to determine truth or falsity of the entire expression, so the p++ in (2) may not be reached - regardless of the ORDER of evaluation. There are, at least, two solutions. 1) One is Coltoff's 1). Why must the ++ be inside? 2) Shift the endpoints of the range of p so as to use ++p in the first place it is used. Thus it is always evaluated. This may be tricky, and in the sense that one needs to be certain of the order, may be harder. For example, suppose the if-expression is a tautology and always TRUE, and suppose the c-compiler were smart enough to recognize that fact. Then no part of the expression would have to be evaluated. Richard
guy@rlgvax.UUCP (05/25/83)
The System III "tolower" is a subroutine, not a macro, so it doesn't evaluate its argument twice. The manual page for the System V "tolower" is the same, so I suspect it is also a subroutine. Guy Harris RLG Corporation {seismo,mcnc,we13,brl-bmd,allegra}!rlgvax!guy
tihor@cmcl2.UUCP (06/07/83)
#R:ariel:-34000:cmcl2:15400003:000:164 cmcl2!tihor Jun 6 22:04:00 1983 (Re: separate compilation) Actually the Ada Reference Manual in essence requires a compiler to support separate compilation to be a validatable Ada (tm) compiler.