"for" loops (was Re: C++ vs. Modula

david wald wald-david at CS.YALE.EDU
Wed Feb 8 14:00:32 AEST 1989


In article <7800004 at gistdev> flint at gistdev.UUCP writes:
>/* Written 12:19 pm  Feb  5, 1989 by atanasoff.cs.iastate.edu!hascall in gistdev:comp.lang.c */
>>   Sure, it works in some simple cases, but how do you propose to
>>   handle:
>>
["do" loop with non-constant start, end and increment]
>>
>>    now we don't know which power of 10 to use, having no "textual"
>>    information from the users program.
>
>From my previous posting: (as George Bush would say: "Read my lips" :-) )
>>>It should be noted that I advocated doing this to "simple" loops where it
>>>works, not to every loop.
>
>I believe we both just said the same thing, so I'll assume you are agreeing
>with me: you just provided an example of a case you can't optimize as I
>stated there would be.
>
>>    Or how about:
>>
>>       do i=0.0, 4.0, 2.0/3.0
>
>The compiler has two choices here:  1. Do the division right away, as you
>just did (something I believe is an error: to use your arguments, "if I wanted
>0.666667 instead of 2/3, I would have said 0.66667!"), or 2. be smart, and
>multiply the denominators through: this is exactly what it is doing in the
>case of decimals.
...
>(How to decide what the smallest integer value to multiply through by is left
>as a 7th grade level arithmetic exercise for the reader.)
>
>In other words, I was already advocating that the compiler do fractions,
>you assumed that I only wanted it to deal with the specific case where
>the denominators in the fractions are powers of 10.  If the user writes
>2/3 in their code instead of 0.667, and the compiler can make use of the
>extra information that 2/3 conveys, then it ought to do so.
>
>I don't think (but I could be wrong: it has happened before :-) ) that
>there is any loop you can write that contains only constants for the
>loop start/end/increment that cannot be converted into an integer
>controlled loop in a straightforward manner.  If you can optimize someone's
>program for speed, you ought to be willing to optimize it for accuracy
>as well.

This bothers me a bit, for the following reason (and I'm switching back
to for(;;) syntax, since I later assume a system with a C-like
preprocessor):

You seem to be advocating different semantics for a for(;;) loop based
on whether the expressions it contains are constant or not.  In a couple
of examples we've seen that the for(;;) construct will loop a different
number of times depending on whether or not the denomonator is
multiplied away.  At what point do you proclaim the compiler "smart
enough"?  Is it enough to deal with constant expressions?  How about
constant expressions hidden by macros?  (Clearly, there's no way of
dealing with the former and not the latter, but you now can have
something which may appear to be in function syntax, but actually turns
into a constant expression.)

What if there's a macro defined as:

#ifdef _SOME_WEIRD_FEATURE_FLAG
#  define macro(x) some_nonconstant_function_of(x)
#else
#  define macro(x) 3
#endif

and you produce code that goes

for(i=0; i<=4; i += 2/macro(j))
    some_expression_affecting_j;

What does your friendly-and-intelligent compiler do?  And how do you, as
programmer, know how long your loop is going to go?  Remember that the
compiler will never see the macro nonsense, only the expressions that
substitute for it.  If you require the programmer to know whether the
macro above evaluates to a constant or not, you are eliminating all the
code-hiding benefits of macros, since the programmer must know what's
inside them.  The programer must also take the feature flag into account
in the middle of a program, perhaps multiple times, whereas the absence
of the "optimization" might allow it to be hidden in a header file.

Finally, as has been stated ad nauseum in this forum, an optimization
should never change the semantics of a program, because you never know
when it's going to be done.  What if a slightly smarter version of this
"optimization" is employed, such that it can find non-constant
expressions that are nevertheless compiler-provably constant for the
duration of the loop.  You get even better benifits, in your terms, but
even more disagreement between compilers that do and don't change their
loop semantics in different circumstances, depending on how good they
are at finding constant expressions.  If I'm writing code, I want to know
how long I'm going to loop, no matter what compiler my code is compiled
with.  That's a fairly basic issue.  If compilers actually "have a
choice" about this sort of interpretation, I don't know this.


============================================================================
David Wald                                              wald-david at yale.UUCP
waldave at yalevm.bitnet                                 wald-david at cs.yale.edu
"A monk, a clone and a ferengi decide to go bowling together..."
============================================================================



More information about the Comp.lang.c mailing list