1

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.)

bob.sacamento
  • 6,283
  • 10
  • 56
  • 115

0 Answers0