Community
cancel
Showing results for 
Search instead for 
Did you mean: 
A__King
New Contributor III
198 Views

Changing the loop range inside the loop

Jump to solution

Is this code standard-conforming?

program hello
    integer :: n = 10, i
    do i = 1, n
        Print *, i
        if (i == 5) n = 6
    end do
end program Hello

 

Note that the value of n changes inside the loop. So is this loop supposed to end at 6 or 10? Both GFortran and Intel ifort end the loop at 10. But is this the standard behavior or compiler-dependent?

 

0 Kudos
1 Solution
IanH
Black Belt
144 Views

I think the previous two responses have misread the assignment as being to the loop index variable.

As stated in the latter post, the iteration count for this form of do loop is determined prior to the start of the first iteration.  Subsequent changes to variables used in determining the iteration count (start, finish or step) do not affect the iteration count of the loop.

(You are not permitted to modify the loop index variable i, but the code shown does not do that.)

The code, and the observed result, conform to the standard (the last value printed will be 10, noting the value of i after the loop terminates will be 11).

If the termination criteria for your loop is dynamic, perhaps use an EXIT statement or the DO WHILE (...) form of do loop.

View solution in original post

8 Replies
mecej4
Black Belt
168 Views

The Fortran standard forbids changing of the loop index variable by the program code inside the loop.

The only permitted change is the automatic incrementing (by m3, if specified; decrementing if m3 is negative; by 1 otherwise) that occurs after each repetition of the loop DO <var> = m1, m2, m3 .

The compiler may take any action, and without notifying you of the violation.

andrew_4619
Valued Contributor III
161 Views

further to mecej4's comments, the loop counters are setup prior to the execution of the loop for the first time. But ultimately your program is not conforming IMO.

IanH
Black Belt
145 Views

I think the previous two responses have misread the assignment as being to the loop index variable.

As stated in the latter post, the iteration count for this form of do loop is determined prior to the start of the first iteration.  Subsequent changes to variables used in determining the iteration count (start, finish or step) do not affect the iteration count of the loop.

(You are not permitted to modify the loop index variable i, but the code shown does not do that.)

The code, and the observed result, conform to the standard (the last value printed will be 10, noting the value of i after the loop terminates will be 11).

If the termination criteria for your loop is dynamic, perhaps use an EXIT statement or the DO WHILE (...) form of do loop.

View solution in original post

andrew_4619
Valued Contributor III
139 Views

You hit the nail head on as usual Ian

jimdempseyatthecove
Black Belt
129 Views

IanH,

In the sketch given, along with the question, implied (IMHO) a termination to be performed after the next iteration (as opposed to exiting at the IF statement.

The better approach would be using a DO WHILE or DO ... WHILE loop or

doExit = n
do i=1,n
 if(i > doExit) exit
 ...
 if(i=5) doExit = 6
 ...
end do

Jim Dempsey

Steve_Lionel
Black Belt Retired Employee
122 Views

The standard describes the execution of a counted DO loop as determining the number of iterations at the start, so changes to the end value within the loop have no effect. I know that the DEC-heritage compilers look to see if the index variable might change within the loop, and change to a tested loop to accommodate. Such a loop would be nonstandard, as specified. 

Changing the end value within the loop should not affect execution. I agree that a test with EXIT would be the right approach if that behavior is desired.

A__King
New Contributor III
108 Views

Thank you all for your responses. I believe @IanH and @Steve_Lionel have the correct answer and the standard behavior is the desired outcome in this code. It is hard to find the answer on the web or in textbooks.

JohnNichols
Valued Contributor I
99 Views

web or in textbooks

Interesting observation -- but the forum is probably better than most text books on Fortran as it is faster. 

If you are looking for say the first non zero value in a array then if you use your method to minimize the time of the loop use exit, if you want the code to be more readable use do while 

Both work.  

Fortran is very old and its beauty is you can keep running programs.  C# can change so fast code from 6 months ago may not run. 

Of course the perfect language is LISP but you need to enjoy a lot of pain as you learn. 

Reply