What is the difference

utzoo!decvax!harpo!seismo!rlgvax!tom utzoo!decvax!harpo!seismo!rlgvax!tom
Thu Apr 28 16:15:53 AEST 1983


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



More information about the Comp.lang.c mailing list