[comp.lang.fortran] Modifying iteration variables in DO loops

john@nmtsun.nmt.edu (John Shipman) (02/02/88)

In section 11.10 of X3.9-1978, the FORTRAN 77 standard (pp. 11-5 to
11-9), there is no statement about prohibiting the modification of a
DO variable within a loop.  The standard defines how this works for
     "DO ... <iter> = <e1>, <e2> [, <e3> ]":

(1) INITIALIZATION.  Compute the values of expressions <e1>, <e2>,
    and <e3>, and call the results M1, M2, and M3; if <e3> is
    omitted, set M3 to 1.  Compute the number of loops:
        <count> = MAX ( INT ( ( M2 - M1 + M3 ) / M3 ), 0 )
    and store this value in a hidden temporary.  Set <iter> to M1.    

(2) TEST.  If <count> is zero, branch to (5).

(3) LOOP BODY.

(4) MODIFICATION.  Add M3 to <iter>.  Decrement <count>.  Go to (2).

(5) (The statement after the end of the loop)

For example, with some mythical standard-conforming compiler, this loop
would be executed twice, and the final value of COUNT would be 5:

           do 86 count = 1, 2
             count = count + 1
      86   continue

I bet NOBODY has a standard-conforming compiler.  From a compiler
writer's point of view, this is inefficient because you have to modify
both <iter> and <count> at the bottom of the loop; this tends to make
your benchmarks look bad.  I bet the politics behind this decision
were pretty convoluted---anybody know the history of this one?

-- 
John Shipman/Zoological Data Processing/Socorro, New Mexico
USENET: ihnp4!lanl!unm-la!unmvax!nmtsun!john
  ``If you can't take it, get stronger.'' --Falline Danforth

msf@amelia.nas.nasa.gov (Michael S. Fischbein) (02/02/88)

In article <1309@nmtsun.nmt.edu> john@nmtsun.nmt.edu (John Shipman) writes:
>In section 11.10 of X3.9-1978, the FORTRAN 77 standard (pp. 11-5 to
>11-9), there is no statement about prohibiting the modification of a
>DO variable within a loop.

From ANSI X3.9-1978 FORTRAN 77, page 11-8, section 11.10.5, line 6:
  ``Except by the incrementation described in 11.10.7, the DO-variable of
    the DO-loop may neither be redefined nor become undefined during ex-
    ecution of the range of the DO-loop.''

Section 11.10.7 describes how the DO-loop's incrementation processing works.
-- 
Michael Fischbein                 msf@ames-nas.arpa
                                  ...!seismo!decuac!csmunix!icase!msf
These are my opinions and not necessarily official views of any
organization.

firth@sei.cmu.edu (Robert Firth) (02/02/88)

In article <1309@nmtsun.nmt.edu> john@nmtsun.nmt.edu (John Shipman) writes:
>In section 11.10 of X3.9-1978, the FORTRAN 77 standard (pp. 11-5 to
>11-9), there is no statement about prohibiting the modification of a
>DO variable within a loop.

ANSI X3.9-1978 11.10.5:

	"Except by the incrementation described in 11.10.7,
	 the DO-variable of the DO-loop may neither be
	 redefined nor become undefined during execution
	 of the range of the DO-loop"

Happy Groundhog Day!

hydrovax@nmtsun.nmt.edu (M. Warner Losh) (02/03/88)

In article <1309@nmtsun.nmt.edu>, john@nmtsun.nmt.edu (John Shipman) writes:
> In section 11.10 of X3.9-1978, the FORTRAN 77 standard (pp. 11-5 to
> 11-9), there is no statement about prohibiting the modification of a
> DO variable within a loop.  The standard defines how this works for
WRONG.

11.10.5 (pg 11-8) EXECUTION OF THE RANGE.  Statements in the range of
a DO-loop are executed until the terminal statement is reached.
Except by the incrementation described in 11.10.7, the DO-variable of the
DO-loop may be neither redefined nor become undefined during the execution
of the range of the DO-loop.

So, in other words, the redefinition of a loop variable is prohibited inside
the range of a loop.  You can't assign a value to a loop variable, that,
according to the standard, is a redefinition of the loop variable.

> 
> For example, with some mythical standard-conforming compiler, this loop
> would be executed twice, and the final value of COUNT would be 5:
> 
>            do 86 count = 1, 2
>              count = count + 1
>       86   continue
> 

WRONG WRONG WRONG WRONG WRONG WRONG WRONG

There is NO CORRECT answer here, since this isn't a standard following
program.  According to section 13.10.5 sighted above, the assignment
to count is NOT ALLOWED IN A STANDARD CONFORMING PROGRAM.

> I bet NOBODY has a standard-conforming compiler. 

WRONG.  Since this is a not a F77 program, you can't feed it to a F77
compiler and say that the compiler is broken.

As a side note : On VMS, the FORTRAN compile gives a warning message telling
me that I was modifying a loop variable.

One final thing, when you quote some text, please make sure that you
have read the supporting text around it before using the quotation
out of context.

-- 
bitnet:	losh@nmt.csnet			M. Warner Losh
	warner@hydrovax.nmt.csnet    ! Don't know if this works, let me know.
csnet:	warner@hydrovax.nmt.edu
uucp:	...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!warner%hydrovax

john@nmtsun.nmt.edu (John Shipman) (02/03/88)

Apologies for my erroneous earlier posting.  I have this problem
trying to stay awake while reading X3 standards.

So, given that you can't modify the iteration variable, what's the
right way to implement a DO loop?  The standard seems to imply that
you use a hidden counter to control the loop, but your benchmarks won't
shine if you have to maintain this counter as well as the visible
iteration variable.

My guess would be that you dispense with the hidden counter and use the
visible iteration variable to control the loop, just making sure that
the number of iterations will be as specified in the standard---right?

Next question: what if you pass the iteration variable to a subroutine
and that subroutine clobbers it?  It would be hard for the compiler
to know that, especially if the subroutine were linked in later.

      program main
        do 83 loop = 1, 2
          call trouble ( loop )
   83   continue
        write ( 6, * )  loop
      end
      subroutine trouble ( arg )
        arg = arg + 1
        return
      end

Does this program conform to the standard?  If not, is there any
reasonable way for the compiler to catch the violation?

-- 
John Shipman/Zoological Data Processing/Socorro, New Mexico
USENET: ihnp4!lanl!unm-la!unmvax!nmtsun!john
  ``If you can't take it, get stronger.'' --Falline Danforth

afb3@hou2d.UUCP (A.BALDWIN) (02/03/88)

The "iteration counter modification" discuss seems to be saying
that most (all) fortran compilers can't do this.  WRONGO....

The DEC VAX/VMS fortran compiler does allow do variable modification
but gives you warnings at both compile and link time......  (I've
tried it, it works, but who would want it!!).

Also, there seems to be a little known fact that "f77" on System V
UNIX was overhauled for System V Release 2 (paging) on both 3B20s
and VAXen.  Its not the same base compiler as the Version 7 one
(on which the BSD compiler is based).  No comments about the other
3B computers and FORTRAN.

Have fun....

Al Baldwin
AT&T-Bell Labs
...!ihnp4!hou2d!afb3


[These opinions are my own....Who else would want them!!!]

hydrovax@nmtsun.nmt.edu (M. Warner Losh) (02/04/88)

In article <1331@nmtsun.nmt.edu>, john@nmtsun.nmt.edu (John Shipman) writes:
> Apologies for my erroneous earlier posting.  I have this problem
> trying to stay awake while reading X3 standards.

After reading through them myself, I recommend them to all those suffering
from insomnia.

> 
> Next question: what if you pass the iteration variable to a subroutine
> and that subroutine clobbers it?  It would be hard for the compiler
> to know that, especially if the subroutine were linked in later.
> 
> [Example deleted]
>
> Does this program conform to the standard?  If not, is there any
> reasonable way for the compiler to catch the violation?

No, this doesn't, as it redefines the loop variable in devious and
subtle ways.

The compiler on VMS (at least DEC's compiler) for FORTRAN-77 flags
this error as a "possible" loop variable modification, even when the
program units are in two different files and compiled at different
times.  Other than this rather trivial check (if this variable is a
loop counter of an active DO-LOOP and it is passed to a subprogram,
then print this warning message), I think that a compiler would have a
hard time finding stuff like this, especially if the program were a
thousand times more complex.  Even if the compiler had all of the
routines to play with (which it isn't supposed to do, since each
program unit is supposed to be a separate unit), I maintain that the
compiler couldn't get this stuff correct in all cases.  Global data
flow analysis is inherently difficult.

There was a point made in this news group a while ago about what standard
conforming compilers had to do.  The consensus was that they need only
interpret correct programs correctly.  With all other programs, all
bets are off, or so the reasoning went.

Good point John, about this topic.  I have had to work with old FORTRAN-IV
programs that do these dastardly things.  When the original author wanted
to end a do loop, he didn't jump to a label outside of the range of the
do-loop, he assigned the upper bounds to the loop variable, and let
the program exit the loop AS IF IT HAD BEEN done normally.  When I got
the program, I was told to make it work.  Yeh.  Right.  Fortunately, all
I needed to do was compile it...and it "appeared" to work.

I wonder how many people have spent hours trying to debug a program that
accidentally modified a loop variable .....



-- 
bitnet:	losh@nmt.csnet			M. Warner Losh
	warner@hydrovax.nmt.csnet    ! Don't know if this works, let me know.
csnet:	warner@hydrovax.nmt.edu
uucp:	...{cmcl2, ihnp4}!lanl!unmvax!nmtsun!warner%hydrovax