conditional expression evaluation question

Tim Olson tim at amdcad.UUCP
Wed Jan 14 10:58:38 AEST 1987


George M. Sipe writes:
+---------------------------------------
|I need to check a string, composed of byte triples, for a null area no
|less than MINSKIP triples in length.  A pointer, cp, is initialized to
|a triplet boundary.  After the test, it must remain on a triplet
|boundary.  Initially, I wrote the following:
|
|	while (cp < end && triples < MINSKIP)
|		if ((*cp++ | *cp++ | *cp++) == 0) ++triples;
|		else triples = 0;
|
|After looking at it, I wasn't absolutely sure that it would perform as
|expected.  My question is "Does C guarantee execution of portions of a
|conditional expression, even when the result is known after partial
|evaluation?".  In my example, if the first byte is non-null, then the
+---------------------------------------

And James Buster Writes:
+---------------------------------------
|C guarantees that a conditional expression will NOT be fully
|evaluated if the result of the expression is known after a
|partial evaluation. You will have to do some restructuring
|of your code if you were counting on full evaluation of a
|conditional expression (as Pascal does).
+---------------------------------------

Well... C only guarantees short-circuit evaluation for the operators
'&&' and '||', not every conditional expression.  Note that the code that
Mr. Sipe includes uses only the bit-wise or '|' operator, so short
circuit evaluation is *not* guaranteed.  Since the ++ operators cause
side-effects, they must be evaluated.

However, there is another problem.  The X3J11 Draft (as I read it,
anyway) says that postfix operators (++ and --) may delay the
incrementing or decrementing side-effect until the next sequence point
is reached which, in this case, is the end of the condition.  Therefore,
the code generated could possibly test the same character 3 times (and
then increment the pointer 3 times!).  Therefore, it seems to me that
the only safe way to write this sequence is (as Mr. Sipes writes later):


	while (cp < end && triples < MINSKIP) {
		if ((*cp | *(cp+1) | *(cp+2)) == 0) ++triples;
		else triples = 0;
		cp += 3;
	}


	Tim Olson
	Advanced Micro Devices
	ihnp4!amdcad!tim



More information about the Comp.lang.c mailing list