Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!rutgers!cmcl2!yale!wald-david From: wald-david@CS.YALE.EDU (david wald) Newsgroups: comp.lang.c Subject: Re: "for" loops (was Re: C++ vs. Modula Message-ID: <49986@yale-celray.yale.UUCP> Date: 8 Feb 89 04:00:32 GMT References: <1611@csuna.UUCP> <7800004@gistdev> Sender: root@yale.UUCP Reply-To: wald-david@CS.YALE.EDU (david wald) Organization: Yale University Computer Science Dept, New Haven CT 06520-2158 Lines: 101 In article <7800004@gistdev> flint@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@yale.UUCP waldave@yalevm.bitnet wald-david@cs.yale.edu "A monk, a clone and a ferengi decide to go bowling together..." ============================================================================