Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!brl-adm!adm!hoey@nrl-aic.arpa From: hoey@nrl-aic.arpa (Dan Hoey) Newsgroups: comp.lang.c Subject: Re: conditional expression evaluation question Message-ID: <2337@brl-adm.ARPA> Date: Wed, 14-Jan-87 13:43:01 EST Article-I.D.: brl-adm.2337 Posted: Wed Jan 14 13:43:01 1987 Date-Received: Thu, 15-Jan-87 00:44:09 EST Sender: news@brl-adm.ARPA Lines: 37 From: "George M. Sipe"Message-Id: <207@rebel.UUCP> Date: 12 Jan 87 21:40:40 GMT ... Does C guarantee execution of portions of a conditional expression, even when the result is known after partial evaluation?.... The semantics of the expression ``((*cp++ | *cp++ | *cp++) == 0)'' includes the side-effect of incrementing ``cp'' three times, and so must be preserved by any correct optimizer. Even if the optimizer, by clever program analysis, could deduce that in some program ``cp'' was already pointing to a block of zeroes, and so could optimize away the entire test (or the entire loop), it would have to leave in the increments. I can't estimate the likelihood of someone writing an opitimizer that is incorrect in this respect. However, the language explicitly leaves the *order* of these side-effects unspecified, except of course that each increment of ``cp'' must be preceded by the corresponding dereference. However, the optimizer is free to postpone all of the increments until after all the dereferences, so you may end up executing something that acts like while (cp < end && triples < MINSKIP) { if ((*cp | *cp | *cp) == 0) ++triples; else triples = 0; cp += 3; } which is not what you want. I think the rewritten code is fine, though I would tend to use cp[1] instead of *(cp+1), and I would also tend to use a conditional-or (||) instead of logical-or (|) and conditional-not (!) instead of a comparison (== 0). But that's just how I write. Dan Hoey