I have the following simple code (which is an example of something I am trying to do in a much more complicated code):
module linkmod
type link
character(len=1) :: name
type(link), pointer :: next => null()
end type link
contains
recursive subroutine tell_name(a)
type(link), target :: a
type(link), pointer :: b !b is useless, except to illustrate my point
integer :: num_outputs = 0
b => a
if (associated(b%next)) call tell_name(b%next)
print *, b%name
num_outputs = num_outputs + 1
print *, num_outputs
end subroutine tell_name
end module linkmod
program driver
use linkmod
type(link) :: a
type(link), pointer :: b
a%name = 'a'
allocate(a%next)
b => a%next
b%name='b'
allocate(b%next)
b => b%next
b%name = 'c'
allocate(b%next)
b => b%next
b%name = 'd'
call tell_name(a)
end program
I compile and run and get the following output:
d
1
c
2
b
3
a
4
Now, I get lucky here because this is the behavior I need, namely, when a call to tell_name()
is exited, b
in the calling instance has retained the value it had before the calling instance made the call, but num_outputs
has been set to what it became in the called instance. (Apologies if that was hard to read. I tried my best there.)
The thing is, I don't really understand why things work this way. Why do not both b
and num_outputs
retain the values they were assigned in the called instance? Or, alternatively, why do they not both re-acquire the values they had in the calling instance, previous to the call?
What is the general rule here? On the other hand, what if I wanted num_outputs
in a calling instance to be unaffected by what happens in any called instance. How would I arrange that?
(BTW, I wrote up an alternative version of the code where I replaced the recursive subroutine
with a derived type procedure, called as
call b%next%tell_name()
I get the exact same behavior with it.)