Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!rutgers!sri-unix!hplabs!cae780!amdcad!tim
From: tim@amdcad.UUCP (Tim Olson)
Newsgroups: comp.lang.c
Subject: Re: conditional expression evaluation question
Message-ID: <14306@amdcad.UUCP>
Date: Tue, 13-Jan-87 19:58:38 EST
Article-I.D.: amdcad.14306
Posted: Tue Jan 13 19:58:38 1987
Date-Received: Wed, 14-Jan-87 05:33:54 EST
References: <207@rebel.UUCP>
Organization: AMDCAD, Sunnyvale, CA
Lines: 52
Summary: multiple side-effects are dangerous...


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