I am experimenting with a recursively defined derived type, where the recursion is via an allocatable component instead of a pointer. This way I hope to avoid having to program a deep copy of the structure. I used this little program:
! chkrecursive.f90 --
! Check a feature: recursively defined derived type with allocatable components
! Does assignment do a "deep" allocation?
!
program chkrecursive
implicit none
type recursive
integer :: chk
type(recursive), allocatable :: next
end type recursive
type(recursive) :: chain1, chain2
chain1%chk = 1
chain2 = chain1
chain1%chk = 2
chain2%next = chain1
chain1%chk = 3
write(*,*) 'chain1: ', chain1%chk , ' - expected: 3'
write(*,*) 'chain2: ', chain2%chk , ' - expected: 1'
write(*,*) 'chain2: ', chain2%next%chk, ' - expected: 2'
chain2%next = chain2
write(*,*) 'chain2: ', chain2%chk , ' - expected: 1'
write(*,*) 'chain2: ', chain2%next%chk , ' - expected: 1'
write(*,*) 'chain2: ', chain2%next%next%chk, ' - expected: 2'
end program chkrecursive
With Intel Fortran oneAPI I get what I expect, but gfortran (version 10.2.0 from Equation Solution on Windows) gives 1 for the last line instead of 2.
I checked my expectations rather carefully, but of course a mistake is still possible. Have I run into a bug in either compiler or is my understanding of such data structures wrong?
I have been using this recursive type pattern with ifort for several years and find it very useful and have not encountered any problems, but, sorry, I have not tried it with gfortran (yet?)
Well, in the program I intend this for I run into a mysterious problem with Intel Fortran: I overload the // operation, but Intel Fortran does not accept that, at least in that full source code, small reproducers were accepted gracefully, which makes me add the epitaph “mysterious” .
Two alternatives come to mind, but both involve descending the derived type and allocating and assigning explicitly (pointer or allocatable components). An allocatable component is attractive as it avoids memory leaks automatically (or should).
As it was said in a few topics already (one of them) support for newer features of derived types in gfortran is not complete yet. Surely PDTs, apparently also recursive DTs.
Just curious: any use case for such a construct? At first glance it looks a bit awkward to me.
We use it for a multi-dimensional population balance, outer array time, then cancer type, then size of primary tumour then secondary spread if appropriate to tumour type etc, but is incredibly flexible especially used as an extension of an abstract data type, where each new layer has procedure pointers to relevant calculation for that layer
I will report it as a bug, now that I know my expectations for this particular program are correct.
The context of my program is the Mathematics of Arrays project (see the thread in this forum). My current implementation is flawed as it can cause self-references (ending in an endless loop ) and I need to be more careful about the references. My first thought was that with allocatable recursive types this would be solved automatically, so I wrote this program to check that.