I have come across a nested do construct in an old code that I am using, and hoping to understand and modernize. It uses the same labelled action statement for termination of the do loops, as well as go to statement. Here is a simplified version, that illustrates the logic of the original code with some otherwise trivial operations:
subroutine original(lim)
k=0
do 10 i=1,4
do 10 j=1,3
k=k-2
if (i>lim) go to 10
k=k+i*j
10 k=k+1
write(*,*) k
return
end
After looking at other questions
on this site (and external resources), this is my
best effort at rewriting the logic of the original code, without obsolescent features (and go to):
subroutine modern(lim)
integer, intent(in) :: lim
integer :: i, j, k
k=0
outer: do i=1,4
inner: do j=1,3
k=k-2
if (i>lim) then
k=k+1
cycle inner
end if
k=k+i*j
k=k+1
end do inner
end do outer
write(*,*) k
end subroutine modern
I tested the codes with the following program, including alternatives for triggering/not triggering the go to statement:
write(*, '(a)') 'original:'
call original(2)
call original(5)
write(*, '(/,a)') 'modern:'
call modern(2)
call modern(5)
end
and it gives the same result for the original and my modern rewrite:
original:
6
48
modern:
6
48
The action statement complicated (for me) rewriting the do loops, one can not simply replace it
with two end do statements, and this is further complicated by the go to. My rewrite required
duplicating the action statement (at the end of the inner loop, and within the body of the if
statement). So my question is this:
- What is the canonical/recommended way for handling the shared labelled action statement?
- Is my
modernsubroutine a correct rewrite of theoriginalone? - Is it possible to rewrite the
originalcode without duplicating the action statement (k=k+1)?