[comp.std.c] Question about regrouping of operands

walter@hpcllz2.HP.COM (Walter Murray) (05/12/88)

Under the proposed C standard, a conforming implementation is
no longer free to disregard parentheses in evaluating an
expression.  At least, the results must be _as_if_ parentheses
were honored.  The Rationale explains that this brings C into
accord with FORTRAN and other languages.

Actually, as I read the proposed standard, ANSI C would seem to
be _more_strict_ than FORTRAN.  For example, FORTRAN requires the
expression X+Y+Z to be _interpreted_ as (X+Y)+Z, but explicitly
permits it to be _evaluated_ as X+(Y+Z), even though the results could
be different.  The proposed C standard seems to require that, in
the absence of parentheses, both the interpretation and the 
evaluation be done left-to-right.  Thus, in C, the expression
X+Y+Z would have to be evaluated as (X+Y)+Z.

Any thoughts?  Am I interpreting the proposed standard correctly?

		   -- Walter Murray

jsb@actnyc.UUCP (The Invisible Man) (05/13/88)

In article <16490001@hpcllz2.HP.COM> walter@hpcllz2.HP.COM (Walter Murray) writes:
)Actually, as I read the proposed standard, ANSI C would seem to
)be _more_strict_ than FORTRAN.  For example, FORTRAN requires the
)expression X+Y+Z to be _interpreted_ as (X+Y)+Z, but explicitly
)permits it to be _evaluated_ as X+(Y+Z), even though the results could
)be different.  The proposed C standard seems to require that, in
)the absence of parentheses, both the interpretation and the 
)evaluation be done left-to-right.  Thus, in C, the expression
)X+Y+Z would have to be evaluated as (X+Y)+Z.

In the absence of parens, X+Y+Z can be evaluated in any order, including
(Z+X)+Y.  Furthermore, if the results are the same, (X+Y)+Z can be
evaluated as X+(Y+Z).  (unless they changed this at the April meeting :-)
-- 
		"Notitiae gratia notitiarum"
				jim (uunet!actnyc!jsb)

karl@haddock.ISC.COM (Karl Heuer) (05/18/88)

In article <881@actnyc.UUCP> jsb@actnyc.UUCP (The Invisible Man) writes:
>In the absence of parens, X+Y+Z can be evaluated in any order, including
>(Z+X)+Y.

Where do you find this in the dpANS?  As I read it, X+Y+Z and (X+Y)+Z are
treated identically, and the latter must be evaluated as written.  (Modulo the
as-if rule.)

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

jsb@actnyc.UUCP (The Invisible Man) (05/19/88)

In article <4049@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
)In article <881@actnyc.UUCP> jsb@actnyc.UUCP (The Invisible Man) writes:
)>In the absence of parens, X+Y+Z can be evaluated in any order, including
)>(Z+X)+Y.
)
)Where do you find this in the dpANS?  As I read it, X+Y+Z and (X+Y)+Z are
)treated identically, and the latter must be evaluated as written.  (Modulo the
)as-if rule.)
)
)Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

As I re-read it, you seem to be correct.  With the discussion of this issue
often abreviated in the phrase "parentheses force grouping" I am surprised
at this and wonder if the current wording truly expresses the intent of the
committee.


-- 
		"Notitiae gratia notitiarum"
				jim (uunet!actnyc!jsb)

gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/20/88)

In article <891@actnyc.UUCP> jsb@actnyc.UUCP (The Invisible Man) writes:
>I ... wonder if the current wording truly expresses the intent of the
>committee.

Damn right it does!  Order of evaluation is no longer ambiguous for
commutative/associative operators.  (Side-effects can in many cases be
deferred until a sequence point.)  When it can be determined that the
rearrangement will have no adverse effect, an implementation can still
generate whatever code its little heart desires.

rbutterworth@watmath.waterloo.edu (Ray Butterworth) (05/20/88)

In article <881@actnyc.UUCP>, jsb@actnyc.UUCP (The Invisible Man) writes:
> In the absence of parens, X+Y+Z can be evaluated in any order, including
> (Z+X)+Y.  Furthermore, if the results are the same, (X+Y)+Z can be
> evaluated as X+(Y+Z).  (unless they changed this at the April meeting :-)

Not true.  (unless they changed this at the April meeting)

When "noalias" first sprang into being, someone suggested that
the Committee had introduced it simply to distract attention from
the more serious changes that they wanted to slip in at the same
time.  They predicted that the Committee would eventually drop
the new qualifier and everyone would cheer and never even notice
the significance of the other new changes.

I really don't believe that the Committee was intentionally that
sneaky, but the effect has been achieved just the same.

Under the new standard, "a + b + c + ... + x + y + z" means that
the value of "a" must be added to that of "b", then the result
added to the value of "c", then ....  This new requirement was
introduced to solve problems of truncation when adding floating
points with a wide range of values.

Of course a compiler doesn't actually have to do the additions
in that precise order, it simply has to behave the same as if
the additions had been done in that order.

On many compilers such integral additions can be done in any
order and still achieve the same result.  The authors of such
compilers won't really have any objections to the change since
they don't have to do anything about it.

But consider a compiler that wants to provide more reliable
software.  Three obvious ways of doing this at no extra cost
are to cause hardware faults when dereferencing a null pointer,
to have a non-zero bit pattern for null pointers, and to cause
hardware faults on integer overflow.  Code that is debugged on
such a compiler will be much more reliable than the same code
debugged in a more "fault-tolerant" environment (e.g. BSD VAX).

Now if integer overflow checking is enabled, the compiler is
no longer free to do the additions in any order it wants.  It
must do them in precisely the order that the programmer has
requested, since the programmer might have specificly requested
that order to prevent overflow.  It is not free to rearrange
the additions, even if most of the operands are constants that
could be collapsed or if many of the sub-additions are the same.
For example, "1 + a+b+c + 2 + a+b+c + 3 + a+b+c + 4" cannot be
optimized to "10 + 3*(a+b+c)", since "3*(a+b+c)" might overflow.

So, when a compiler is being written, a big decision must
be made about providing overflow checking.  With the check,
the resulting code will be more reliable but it will be
a lot slower since much of the optimization can no longer
be performed.  Consider how compilers are marketed (dhrystones
vs. better error checks) and then guess which way the decision
will go?

There was a posting in comp.lang.c recently about a company that
had decided against using non-0 null pointers and the hardware's
ability to trap them simply because there was too much bad code
in the real world that wouldn't run properly on it.

With this change to the order of additions, the world will again
lose out on compilers that help us to write more reliable code.
How many compilers will do the checking (that otherwise would have
been for free) if it means loosing speed?  Not many.

There is no question that it is nice for a programmer to be able
to specify the order of operations when he needs it, but the
Committee has made it so that he specifies the order whether
he needs it or not.  And even in those cases where the order
is important, the programmer has no way of indicating that this
section of code really is order-sensitive other than by putting
in noisy comments.

Originally, the Committee must have realized these problems and
so they introduced a new syntax, "a + +(b+c) + d", that forced
"b+c" to be added first.  This was a good thing, but the unary
plus notation was ugly and non-obvious and many people objected
to it.  In response, the Committee dropped the special meaning
associated with the unary plus, but instead of introducing a
much more esthetic and meaningful replacement, "a + [b+c] + d",
that would make order-critical code obvious, they chose to
say that ALL operations will be considered order-critical.

That has to be one of the worst decisions the Committee made.
I'll never understand why they did it.

One person: My car handles badly when it goes over 60 mph.
Committee:  Here's an airfoil you can use to make it more stable.
Everyone:   It's ugly.
Committee:  OK then.  From now on, absolutely no one goes over 55 mph.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/21/88)

In article <19000@watmath.waterloo.edu> rbutterworth@watmath.waterloo.edu (Ray Butterworth) writes:
>Now if integer overflow checking is enabled, the compiler is
>no longer free to do the additions in any order it wants.  It
>must do them in precisely the order that the programmer has
>requested, since the programmer might have specificly requested
>that order to prevent overflow.

This is correct.  However, it has not been demonstrated that a
serious loss of efficiency will necessarily result from removal
of this kind of optimization.  The only way I can imagine it being
significant would be for the hardware to provide extremely poor
data caching (for example, only a couple of data registers) so
that the compiler is forced to resort to more expensive caching
(for example, via push/pop).  My feeling is that people with
hardware like that already have much worse problems to worry about.

>With this change to the order of additions, the world will again
>lose out on compilers that help us to write more reliable code.

Overflow checking does not help in the writing of more reliable
code, but rather in the detection of unreliable code at a hard-to-
predict moment during actual execution.  There are certainly cases
in which I would prefer such an application to keep running even
with a slightly wrong behavior rather than simply fault.

>I'll never understand why they did it.

I can't help you there.

markhall@pyramid.pyramid.com (Mark Hall) (05/24/88)

In article <7952@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <19000@watmath.waterloo.edu> rbutterworth@watmath.waterloo.edu (Ray Butterworth) writes:
>>[ a + b + c + ... + x + y + z ]
>>Now if integer overflow checking is enabled, the compiler is
>>no longer free to do the additions in any order it wants.  It
>>must do them in precisely the order that the programmer has
>>requested, since the programmer might have specificly requested
>>that order to prevent overflow.
>
>This is correct.  However, it has not been demonstrated that a
>serious loss of efficiency will necessarily result from removal
>of this kind of optimization.  
>

A `perfect' Multi-Flow type machine (or any machine which 
supports fine-grain parallel execution), is able to evaluate 
this expression (assuming N is the number of operations) in 
		log N
		   2
instructions, given no restriction on execution order.  Constraining
such a machine to the serial execution order of the above expression,
which requires N instructions, is indeed a serious loss of efficiency.

I'll concede, however, that such expressions with large N are rare.
 
Mark Hall {seismo | sun | decwrl}!pyramid!markhall