Fortran Block DO construct


Example

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.