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

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.