Pietro said:
Eric Sosman wrote:
Pietro Cerutti wrote:
Hi group,
here I come with a question which is quite simple per se, but for which
I can't find an answer.
Does the C standard guarantee that inside an expression such as
(x && y)
"y" is not evaluated if "x" evaluates to 0?
Yes.
Are we guaranteed that a conforming compiler cannot, for whatever
purpose, evaluate "y" first?
Yes. If you study the generated code you might doubt
this "yes," because in some situations you might find that
the evaluation of y begins before the evaluation of x is
finished (imagine x and y not as single variables, but as
more complicated expressions). But don't worry: the outcome
must be "as if" y's evaluation is strictly later than x's,
or doesn't happen at all if x is zero. No side-effects or
errors that could occur in the evaluation of y can happen
until after x is finished and found to be non-zero; if x
turns out to be zero then no side-effects or errors from
evaluating y can occur at all.
Thank you for your answer (and also thank you CryptiqueGuy for yours,
which is basically the same).
I'm only a bit worried about your sentence "[...] in some situations you
might find that the evaluation of y begins before the evaluation of x".
What does it mean, practically?
Essentially, it means "Don't let the generated code
confuse you." Imagine a y that is a multi-term expression,
and suppose that some parts of y will be used no matter
how the test comes out:
if (x && r + s > t)
printf ("Boo!\n");
z = r + s + t;
Here, y is the entire expression `r + s > t', which we have
said will only be evaluated if x is non-zero. But the compiler
might decide to evaluate the sub-expression `r + s' early, since
it will produce no side-effects (let's assume) and the sum will
be needed anyhow. The compiler might do something like
tmp = r + s;
if (x && tmp > t)
printf ("Boo!\n");
z = tmp + t;
... and this would be perfectly all right. The compiler could
*not* do this if evaluating `r + s' could produce a side-effect
(overflow generating a signal, for instance), because the value
of x should govern whether the signal occurs before or after the
output, and in the rewritten code it would always occur first.
But if the compiler can figure out that `r + s' has no side-
effects to worry about, it can evaluate that component of y
before it finishes evaluating x.
Practical effects: From the C programmer's perspective,
none, because the program operates "as if" x==0 completely
suppressed the evaluation of y. Someone studying the compiled
code might be confused by seeing some parts of y evaluated
early, but that's just a distraction. The only reason I brought
it up was in response to your phrase "for whatever purpose."