I have a subroutine that declares i
and passes it to other small subroutines. Within those small subroutines there are declared other variables with the same name, i.e i
, and it is internally used. Once out of the small subroutines, one would expect to have the same i
value that was originally passed, however that is not the real situation and i
contains the value of the last parameter assigned within the small subroutines. Here is a brief example:
subroutine smallSub1(i)
integer i,start,end
start=i
end = start +10
do i=start, end
write(*,*) i
enddo
end subroutine smallSub1
subroutine caller
integer i
i = 1
call smallSub1(i)
write(*,*) i
end subroutine caller
My question is, how could I avoid this behavior in F77?
My concern here is: think about a situation where a subroutine is a black box, and you just need to pass an integer, but you do not want that integer value to change from the smallSub1
subroutine. The variables start
and end
would depend on the value of i
however they should not replace the original value of i
out of smallSub1
In the code example given there are two variables i
: one in each subroutine. In subroutine caller
the i
is a local variable, and in the subroutine smallSub1
it is a dummy argument.
When you have call smallSub1(i)
you are associating the two i
variables with each other through argument association. In this simple case, then, any change to i
in smallSub1
affects the i
in caller
. There is how argument association works here.
Traditionally one did have black-boxes where an argument is changed in the subroutine when that wasn't desired. Where it is used as a work-space, for example. In that case, one would do something like
inew = i
call smallSub1(inew)
... continue using i
In this case, however, one can easily (I imagine) change the subroutine. Introduce an extra local variable:
subroutine smallSub1(i)
integer i ! Dummy argument - we don't want to change it
integer start,end
integer j ! Local variable - we're quite free to change it
! In general, we'd have j=i at the start and use that instead
start=i
end = start +10
do j=start, end
write(*,*) j
enddo
end subroutine smallSub1
And with modern Fortran one even has the value
attribute, which can be applied to the dummy argument allowing one to change it without impact on the actual argument.