From: torek@horse.ee.lbl.gov (Chris Torek)
Newsgroups: comp.lang.c
Subject: Re: Order of evaluation?
Date: 8 Nov 1992 09:30:15 GMT
Organization: Lawrence Berkeley Laboratory, Berkeley
Reply-To: torek@horse.ee.lbl.gov (Chris Torek)
NNTP-Posting-Host: 128.3.112.15

In <1dau8nINNk59@uranium.sto.pdb.sni.de> Josef Moellers
<mollers.pad@sni.de> writes:
>>E.g. in an expression like
>>	a() * b() * c() * e() * f() * g()
>>the compiler might decide to generate code to test the intermediate
>>result to be 0, in which case the rest of the expression might be
>>dropped.

In article <1992Nov6.163023.1649@mksol.dseg.ti.com> mccall@mksol.dseg.ti.com
(fred j mccall 575-3539) writes:
>I don't think this applies.  I believe the whole 'expression' must be
>evaluated and the compiler is not allowed to short-circuit that.

Fred McCall is correct, modulo caveats about `observable behavior'.

`Order of evaluation', `precedence', and `sequence points' are all
different issues in C.

Sequence points are an ANSI C invention---and a good one---that allow
you to define a partial order on expression evaluation.  If two
expressions e1 and e2 are separated by one or more sequence points, you
(the programmer) are assured that all side effects in e1 have
apparently happened before e2 is apparently started.  Thus, given:

	i++; i += i;	/* sequence points at semicolons */

we can tell what we will get if we print (or otherwise examine) the
value in i, although we do not actually know whether we are seeing the
value *really* in i, or just something that *looks exactly the same*
(and is there any difference? if a tree falls in the woods and there
is no one to hear it, is that noise pollution?).

Precedence is a syntax issue; ANSI C uses a grammar that avoids it
entirely, but there are equivalent precedence grammars that are easier
to remember, so people tend to use the latter.  Unfortunately

Order of evaluation is generally not defined in C.  This is modified by
sequence points:  Because we know side effects have occurred---and
remember that output is a side effect---any time we attempt to observe
the order of an evaluation containing sequence points, that observation
will show the order guaranteed by those sequence points.

>... it would have to be evaluted completely (all functions called)
>even if the first multiplication produced a zero.  In other words,
>side effects of the functions must happen.

Right.  Note, however, that the order in which those functions are
called is undefined---and if it turns out that any function does
nothing, the compiler is free to omit the call, since we will not be
able to tell that it did so.  Similarly, the compiler could omit the
rest of the multiplies if the first produces 0, because again we will
not be able to tell.

The only way to find out whether the compiler is using smoke and
mirrors to *simulate* doing everything is to go outside the C
language.  For instance, you could disassemble the object code to see
whether

	i++; i += i;

was compiled as `add 1 to i, then add i to i' or as `i = (i + 1) << 1'.
A printf() in between will not suffice, because the compiler can simply
generate different code that time.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 510 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov