A do
construct is a looping construct which has a number of iterations governed by a loop control
integer i
do i=1, 5
print *, i
end do
print *, i
In the form above, the loop variable i
passes through the loop 5 times, taking the values 1 to 5 in turn. After the construct has completed the loop variable has the value 6, that is, the loop variable is incremented once more after the completion of the loop.
More generally, the do
loop construct can be understood as follows
integer i, first, last, step
do i=first, last, step
end do
The loop starts with i
with the value first
, incrementing each iteration by step
until i
is greater than last
(or less than last
if the step size is negative).
It is important to note that since Fortran 95, the loop variable and the loop control expressions must be integer.
An iteration may be ended prematurely with the cycle
statement
do i=1, 5
if (i==4) cycle
end do
and the whole construct may cease execution with the exit
statement
do i=1, 5
if (i==4) exit
end do
print *, i
do
constructs may be named:
do_name: do i=1, 5
end do do_name
which is particularly useful when there are nested do
constructs
do1: do i=1, 5
do j=1,6
if (j==3) cycle ! This cycles the j construct
if (j==4) cycle ! This cycles the j construct
if (i+j==7) cycle do1 ! This cycles the i construct
if (i*j==15) exit do1 ! This exits the i construct
end do
end do1
do
constructs may also have indeterminate loop control, either "forever" or until a given condition is met
integer :: i=0
do
i=i+1
if (i==5) exit
end do
or
integer :: i=0
do while (i<6)
i=i+1
end do
This also allows for an infinite do
loop via a .true.
statement
print *,'forever'
do while(.true.)
print *,'and ever'
end do
A do
construct may also leave the order of iterations indeterminate
do concurrent (i=1:5)
end do
noting that the form of loop control is the same as in a forall
control.
There are various restrictions on the statements that may be executed within the range of a do concurrent
construct which are designed to ensure that there are no data dependencies between iterations of the construct. This explicit indication by the programmer may enable greater optimization (including parallelization) by the compiler which may be difficul to determine otherwise.
"Private" variables within an interation can be realized by use of a block
construct within the do concurrent
:
do concurrent (i=1:5, j=2:7)
block
real tempval ! This is independent across iterations
end block
end do
Another form of the block do
construct uses a labelled continue
statement instead of an end do
:
do 100, i=1, 5
100 continue
It is even possible to nest such constructs with a shared termination statement
do 100, i=1,5
do 100, j=1,5
100 continue
Both of these forms, and especially the second (which is obsolescent), are generally to be avoided in the interests of clarity.
Finally, there is also a non-block do
construct. This is also deemed to be obsolescent and is described elsewhere, along with methods to restructure as a block do
construct.