Silverfrost Forums

Welcome to our forums

Why this is illegal?

20 Mar 2018 9:13 #21640
iEnd = 2       
  do i=1,iEnd
    if(i.eq.2) iEnd=4
    print*,i
  enddo
end

Last i it prints is i=2 instead of i=4. I'd understand that do loop refused to change do loop variable i but what in Fortran world would be hurt by dynamically changing doo loop min and max values???? Is this again the Fortran Standard mental sheez?

20 Mar 2018 9:48 #21641

The loop count is calculated just once, when the DO construct is begun. Subsequent changes to the variables used in the <start>, <end> and <increment> expressions do not affect the loop count. However, such changes can affect whether a premature EXIT, or a CYCLE statement, are executed.

See davidb's post of Feb. 20 in https://forums.silverfrost.com/Forum/Topic/3274 .

Over the years, working with codes that were decades old, I have seen DO index variables abused quite a bit. In one code, the DO index was passed as an argument in a subroutine call inside the loop, and the subroutine changed the value of the index variable.

If you want a free-wheeling DO loop, you may use a

DO WHILE(<condition>) <statements> END DO

block, or a plain

DO <statements> END DO

construct.

... but what in Fortran world would be hurt by dynamically changing do loop min and max values?

I can imagine Col. Cathcart asking Yossarian such a question (see Heller's novel 'Catch-22' ).

20 Mar 2018 12:11 #21642

If you look at this example of DO loop which is a sibling of my example above with 'classical' DO loop of Fortran-66 era or even before that you can see that its finishing condition is calculated every time with no problems.

i=0
iEnd = 4       
  do while (i <= iEnd) 
    i=i+1
    if(i.eq.2) iEnd=2
    print*,i 
  enddo 
end

So nothing prohibits classical DO loop to do the same. Actually not doing that looks counterintuitive, too over-restricting and obsolete.

20 Mar 2018 12:35 #21643

Quoted from DanRRight If you look at this example of DO loop which is a sibling of my example above with 'classical' DO loop of Fortran-66 era or even before that you can see that its finishing condition is calculated every time with no problems.

i=0
iEnd = 4       
  do while (i <= iEnd) 
    i=i+1
    if(i.eq.2) iEnd=2
    print*,i 
  enddo 
end

So nothing prohibits classical DO loop to do the same. Actually not doing that looks counterintuitive, too over-restricting and obsolete.

'Nothing'? Any Fortran standard newer than Fortran-66 does!

The Fortran Standard (77, 95, 2003, ...) is quite explicit about how the DO loop with loop control of the type <int_expr1>, <int_expr_2>[, <int_expr_3] is to be executed. Please read 8.1.4.4 of the Fortran 95 standard, or read DavidB's post, where he described the operation of this type of DO.

Old (66, IV, II) Fortran compilers, of course, had a different view, and some 80's and 90's compilers had a switch to replicate the old behavior. FTN95 still has the /DO1 option to support the 'at least one-trip DO'. We should not write code today that requires that kind of treatment.

21 Mar 2018 12:18 #21650

Mecej4, DavidB did not discuss explicitly possibility of dynamic changing start and end of DO loop. We even discussed here ones the possibility of dynamic changing DO loop variable i like in

DO i=iStart, iEnd

and there were no strict opposition for that besides the rulings of the Standard. Heard there exist other than Fortran compilers which allow dynamically changing even all three: i, iStart and iEnd. I'd probably agree with not allowing for using floating point numbers for them as this has hidden problem with the rounding of FP numbers but still do not see reasons for the restrictions we are discussing above

21 Mar 2018 1:11 #21651

Dan,

The change to DO loop cycles was one of the more significant changes at F77. It has become a significant property of Fortran DO loops. If you want to vary the loop cycles, you have 'DO while' or use 'DO' and manage the loop variable and exit.

John

21 Mar 2018 1:18 #21653

Quoted from DanRRight Mecej4, DavidB did not discuss explicitly possibility of dynamic changing start and end of DO loop. We even discussed here ones the possibility of dynamic changing DO loop variable i like in

DO i=iStart, iEnd

and there were no strict opposition for that besides the rulings of the Standard. Heard there exist other than Fortran compilers which allow dynamically changing even all three: i, iStart and iEnd.

How on earth can you change the start after the DO loop has been started?

The for loop of C does what you seem to want. You can also write in Fortran:

i = iStart; DO WHILE (i ⇐ IEND); ...I = ..; IEND = ..; ... ; END DO

Try the following example, which is a modification of one that I found on the Web.

      program SmallLoopWrong
        integer i,j
        j=10
        do i = 1, j
           write (*,*) i
           if (i .eq. 10) then
              j = i+1              ! ERROR. Programmer wants an extension!
           end if
        end do
        print *,'i,j = ',i,j
      end

How many lines should the program print?

Try various compilers on this program. What does running the program give you?

Try to get a compiler to help you with locating this 'bug'.

21 Mar 2018 2:59 #21654

Quoted from mecej4

How on earth can you change the start after the DO loop has been started?

Same as iEnd above 😃

iStart = 1       
iEnd   = 4        
  do i=iStart, iEnd
    if(i.eq.2) iStart=4 
    print*,i 
  enddo 
end

Quoted from JohnCampbell Dan,

The change to DO loop cycles was one of the more significant changes at F77. It has become a significant property of Fortran DO loops. If you want to vary the loop cycles, you have 'DO while' or use 'DO' and manage the loop variable and exit.

John, Such damn inconsistences that some DO constructs allow changing its operation conditions and some don't caused me one week of loss for unexplainable errors over 20 years

21 Mar 2018 4:38 #21656

The standard says:

'The number of iterations of a loop may be determined at the beginning of execution of the DO construct, or may be left indefinite ('DO forever' or DO WHILE). In either case, an EXIT statement (8.1.4.4.4) anywhere in the DO construct may be executed to terminate the loop immediately.'

It also says:

'Except for the incrementation of the DO variable that occurs in step (3), the DO variable shall neither be redefined nor become undefined while the DO construct is active.'

The standard doesn't forbid changing m1, m2, or m3 in the loop as far as I know, but such changes don't affect the number of loop iterations. They can't because the number of iterations is calculated at the beginning, before the loop is executed.

Knowing the number of iterations up front allows optimizing compilers to optimize the loop effectively (techniques as loop-unrolling, swapping loops, merging loops).

The loop

do i=1,m2
   <body of loop>
end do

is equivalent to:

i = 1
count = max(m2, 0)  ! <-- loop is executed count times
c = count
10 if (c .eq. 0) goto 20
   <body of loop>
   c = c - 1
   i = i + 1
   goto 10
20 continue

A more general equivalence is given in the post mecej4 refers to.

As John points out you can do all manner of complicated loops if you use the indefinite 'DO forever' type with EXIT. But don't expect much optimization in such cases.

22 Mar 2018 8:03 #21659

DavidB,

Great, since the only serious negative objection from dynamic changing iStart, iEnd and iStep (and probably even loop variable i itself DO i=iStart, iEnd, iStep) could potentially be difficulties of compiler optimization (not always necessarily so, sure by far not) then from this follows pretty satisfactory solution for both sheep and wolves:

  1. Users who change these variables dynamically get the compiler warning 'Dynamically changing DO loop controlling variables may prevent compiler optimization'

  2. As an extension of Standard, all DO loop controlling variables are not just calculated ones before the loop start but can be changed dynamically at any moment during its run.

How about that?

22 Mar 2018 9:50 #21660

Dan, the title of the thread is misleading. There is nothing 'illegal' about the short example code that you started with. Your complaint is really about how the loop is executed. You expect different behavior than what the standard prescribes.

If you want your request to be taken seriously, you will need to do far more work to prepare and justify your request. You will need to consider all possible circumstances and variations, write down a precise and complete prescription of how the loop ought to behave, why your proposed interpretation of DO would be better than the present behavior, and explain why you think that your requested behavior should be imposed on everyone. You should also be prepared to do a cost versus benefit analysis, and to justify why you do not want to use the already available DO WHILE facility.

Quoted from DanRRight ... then from this follows pretty satisfactory solution for both sheep and wolves: ... How about that

Consider this:

iDan = iWolf
do i=iBeg, iEnd
...
   if(i.eq.2)iDan = iSheep
...
end do

and the value of iDan controls how the loop behaves, i.e., sheepish or lupine.

22 Mar 2018 9:52 #21661

Quoted from DanRRight Such damn inconsistences that some DO constructs allow changing its operation conditions and some don't caused me one week of loss for unexplainable errors over 20 years

Dan, Your original post has been illegal for 41 years !! There is a Australian cinema quote from 'The Castle' that could apply here : “Tell him he’s dreamin'”

22 Mar 2018 10:05 #21662

John, if we let Dan build castles in the air, he could one day demand that the optional increment expression (the i3 in DO i = i1, i2, i3) should be allowed to be changed in the loop; if that change involves i3 = -i3, Dan will have created an UNDO loop lurking inside a DO loop!

22 Mar 2018 10:24 #21663

Quoted from JohnCampbell

Your original post has been illegal for 41 years !!

This is why when i asked my colleagues how their different compilers behave in this case they responded 'Forget that dinosaurian Fortran. iEnd is just a usual variable. Of course in our case it can be changed (though not recommended)'. This is exactly what i propose, no one will be hurt. If you don't want it - do not use it, all will stay the same besides it's me who decide not somebody else.

The thick fog is actually much thinner if any then Mecej4 have been painting: the Standard with its 'The number of iterations of a loop may be determined at the beginning of execution of the DO construct, or may be left indefinite' does say MAY but not say that it MUST. So i'd go ahead and fix it returning to 'classic' DO loop some common sense waiting for 41 years.

Please login to reply.