[comp.std.c] Order of Evaluation

gould@physics.usc.edu (Christopher Gould) (11/18/89)

	This is a question about the justification for pANS _not_
making a change from K&R-1:

	Why is the order of evaluation of subexpressions undefined?
This applies either for subexpressions of most binary operators, or as
arguments in function calls.  Specifically, in the following example,
it is presently undefined as to whether the loop adds the even elements
of a[] with the odd elements of b[], or vice versa:

		int a[SIZE], b[SIZE], i, j;
		for ( i=0 ; i < SIZE-2 ;    )
			j = a[i++] + b[i++];

Of course, this loop could easily be rewritten to specify which one is
desired by moving the i++ into the loop statement, and giving an offset
to the appropriate array index.  This question is not about style.

	What I am asking is, what would go wrong if a new Standard were
to say, for example, you always evaluate left to right.  Then we would
get a[0] + b[1] + a[2] + ....   Since the order of evaluation has never
been guaranteed, a new Standard establishing an order of evaluation
(whatever choice one might make) could not break any currently working
code.  Furthermore, it would reduce the number of ambiguous statements
legally constructed within the language.  (Whether this is in itself a
"good thing" is perhaps the real issue.)

	Incidentally, the above example is a case where parentheses
cannot be used to force the order of evaluation.
_________________

Christopher M. Gould - Univ of Southern Calif - Dept of Physics   (213)743-8521
Internet: gould@usc.edu    Bitnet: gould@uscvm    UUCP: uunet!usc!physics!gould

bailey@jacobs.CS.ORST.EDU (Kirk Bailey) (11/18/89)

I'm curious about the fate of the changed floating point evaluation
constraints which were a part of some of the intermediate dpANSI "C" documents;
the idea being that the programmer could be assured of a fixed evaluation
order without requiring the use of temps.  The current doc's I have seem to
no longer mention this (or the synchronization aspect of unary '+')?

On an unrelated front:  Is it conforming practice to cast the value returned
from a function call to void when the function returns a struct or union?
Granted that a nice compiler will allow this, I can't find anything explicit
about it in the std...

Does any system have public ftp access to an archive of this group (for offline
grepping about these sorts of questions)?

	Thanks-in-advance,

		Kirk Bailey (bailey@mist.cs.orst.edu)

henry@utzoo.uucp (Henry Spencer) (11/19/89)

In article <21265@usc.edu> gould@physics.usc.edu (Christopher M. Gould) writes:
>	Why is the order of evaluation of subexpressions undefined?

(1) Because compilers can optimize better if they are free to rearrange
	subexpressions.  Often a lot better.

(2) Because [mount pulpit] you shouldn't be depending on such ugliness
	anyway, so it shouldn't make a difference.

>... it would reduce the number of ambiguous statements
>legally constructed within the language.  (Whether this is in itself a
>"good thing" is perhaps the real issue.)

Good programmers simply avoid the ambiguity.  I can't see that it does
any harm.  Attempting to legislate good programming does not work.
-- 
A bit of tolerance is worth a  |     Henry Spencer at U of Toronto Zoology
megabyte of flaming.           | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

henry@utzoo.uucp (Henry Spencer) (11/19/89)

In article <13871@orstcs.CS.ORST.EDU> bailey@jacobs.CS.ORST.EDU.UUCP (Kirk Bailey) writes:
>...the programmer could be assured of a fixed evaluation
>order without requiring the use of temps.  The current doc's I have seem to
>no longer mention this (or the synchronization aspect of unary '+')?

Look very carefully at the wording about parentheses.  Compilers are now
required to consider parentheses as mandating order of evaluation, not
just grouping.  (I personally liked unary plus better, but...)

>On an unrelated front:  Is it conforming practice to cast the value returned
>from a function call to void when the function returns a struct or union?

The Constraints section of 3.3.4 contains an exception that makes it legal
to cast anything to void.
-- 
A bit of tolerance is worth a  |     Henry Spencer at U of Toronto Zoology
megabyte of flaming.           | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

gwyn@smoke.BRL.MIL (Doug Gwyn) (11/19/89)

In article <21265@usc.edu> gould@physics.usc.edu (Christopher M. Gould) writes:
> Why is the order of evaluation of subexpressions undefined?

Why should it be?

Allowing implementations flexibility in this regard can lead to more
efficient generated code.

If a programmer wants to ensure a particular sequence of calculation,
C provides sufficient tools to do so.  Use them.

gwyn@smoke.BRL.MIL (Doug Gwyn) (11/19/89)

In article <13871@orstcs.CS.ORST.EDU> bailey@jacobs.CS.ORST.EDU.UUCP (Kirk Bailey) writes:
-I'm curious about the fate of the changed floating point evaluation
-constraints which were a part of some of the intermediate dpANSI "C" documents;
-the idea being that the programmer could be assured of a fixed evaluation
-order without requiring the use of temps.  The current doc's I have seem to
-no longer mention this (or the synchronization aspect of unary '+')?

Unary + is no longer the way to do this.  Use parentheses instead.

-On an unrelated front:  Is it conforming practice to cast the value returned
-from a function call to void when the function returns a struct or union?
-Granted that a nice compiler will allow this, I can't find anything explicit
-about it in the std...

If it is allowed by the grammar and does not violate Constraints or
Semantics, then it is allowed in a strictly conforming program.

walter@hpclwjm.HP.COM (Walter Murray) (11/21/89)

Doug Gwyn writes:
> In article <13871@orstcs.CS.ORST.EDU> bailey@jacobs.CS.ORST.EDU.UUCP (Kirk Bailey) writes:
> -I'm curious about the fate of the changed floating point evaluation
> -constraints which were a part of some of the intermediate dpANSI "C" documents;
> -the idea being that the programmer could be assured of a fixed evaluation
> -order without requiring the use of temps.  The current doc's I have seem to
> -no longer mention this (or the synchronization aspect of unary '+')?

> Unary + is no longer the way to do this.  Use parentheses instead.

There are times when the parentheses aren't even needed.  ANSI C guarantees
that
   p = q + r + s;
will behave exactly the same as
   p = (q + r) + s;
In this respect a standard-conforming C compiler will actually have
less latitude than a FORTRAN compiler when it comes to rearranging
expressions.

Walter Murray
----------

davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) (11/21/89)

In article <12570034@hpclwjm.HP.COM> walter@hpclwjm.HP.COM (Walter Murray) writes:

| There are times when the parentheses aren't even needed.  ANSI C guarantees
| that
|    p = q + r + s;
| will behave exactly the same as
|    p = (q + r) + s;

  Could you quote sections on that? I don't seem to find the part which
says that expressions are evaluated left to right.
-- 
bill davidsen	(davidsen@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen)
"The world is filled with fools. They blindly follow their so-called
'reason' in the face of the church and common sense. Any fool can see
that the world is flat!" - anon

walter@hpclwjm.HP.COM (Walter Murray) (11/23/89)

Wm E Davidsen Jr writes:

> In article <12570034@hpclwjm.HP.COM> walter@hpclwjm.HP.COM (Walter Murray) writes:

>| There are times when the parentheses aren't even needed.  ANSI C guarantees
>| that
>|    p = q + r + s;
>| will behave exactly the same as
>|    p = (q + r) + s;

>  Could you quote sections on that? I don't seem to find the part which
>says that expressions are evaluated left to right.

I thought I might get challenged on that!  First, let me emphasize
what I'm NOT saying.  Consider a more general example:

   double sum, x(), y(), z();
   sum = x() + y() + z();

Functions x, y, and z may have side effects.  I am not saying anything
about the order in which those side effects will occur.  The
actual call to z may occur before the calls to x and y.  What I am
saying is that, of the two additions in the expression, the addition
of x() and y() will be performed first, then z() will be added to
that result.

The implementation is free to rearrange things only if it can't make a
difference.  For floating-point arithmetic, of course, it CAN make a
difference.

This is covered in an example in 2.1.2.3.  If you have the December 7,
1988, edition of the dpANS, see page 9, line 46, through page 10, line 21.

I realize that examples are not part of the Standard, but they do
attempt to convey what the Committee members intended for the Standard
to say.  To prove my original assertion from the Standard itself, the
best I can do is to cite the syntax for additive operators (3.3.6),
which defines '+' as a left-associative operator, and then cite
the third paragraph of 3.3, which implies that the syntax can
specify order of evaluation.

Maybe someone else can present a stronger argument in support of
the example I am referring to.

Walter Murray
walter@hpda.HP.COM
---