Allocatable derived types with allocatable members in F95

Dear all,

I hope this is right place to post this question.
I would like to know if it is possible to define allocatable derived types with allocatable members.
I give an example in the code below. I would expect that this would not work because at the time of the first allocate() call it is not yet known how much memory is needed, since the size of member is not yet known. Nevertheless, this seems to work in PGI VF (F95). But I’m afraid that there may be an out-of-bounds problem here, that’s going unnoticed.

If this is correct programming then my next question is: can one do this with deeper levels of nesting, e.g. allocatable derived types with allocable derived-type-members, with allocatable members, etc.

Thanks in advance.

cheers,
Maarten



program prog
implicit none

integer :: i
type test_type
  real, allocatable :: member(:)
end type
		
type(test_type), allocatable :: test(:)
		
allocate(test(10))
do i=1,10
  allocate(test(i)%member(10))
end do
end program prog

Hi Maarten,

I would like to know if it is possible to define allocatable derived types with allocatable members.

Sure. This was added as part of the F95 standard.

If this is correct programming then my next question is: can one do this with deeper levels of nesting, e.g. allocatable derived types with allocable derived-type-members, with allocatable members, etc.

I’ve forgotten if this if F95 of F2003, but this should be fine as well.

Hope this helps,
Mat

Hi,

thanks for the fast answer, Mat!

Concerning my second question (nesting of allocatable derived types): since this is what I plan to do for my code I just want to be sure that that I made clear what I have in mind.
I’ve included some example code below. This compiles and runs fine with my PG VF (F95). Is this correct programming?

Thanks,
Maarten

program prog

	implicit none
	integer :: n_lvl1 = 3;
	integer :: n_lvl2 = 3;
	integer :: n_lvl3 = 3;
	integer :: i, j

	type test_lvl2_type
		real, allocatable :: test_lvl3(:)
	end type

	type test_lvl1_type
		type(test_lvl2_type), allocatable :: test_lvl2(:)
	end type
	
	type(test_lvl1_type), allocatable :: test_lvl1(:)

	allocate(test_lvl1(n_lvl1))
	do i=1,n_lvl1
		allocate(test_lvl1(i)%test_lvl2(n_lvl2))
		do j=1,n_lvl2
			allocate(test_lvl1(i)%test_lvl2(j)%test_lvl3(n_lvl3))
			test_lvl1(i)%test_lvl2(j)%test_lvl3(:) = j
			print *, test_lvl1(i)%test_lvl2(j)%test_lvl3
		end do
	end do

end program prog

Looks fine to me. Probably should deallocate your memory in the same way using do loops, but it’s not an issue in this small example.

  • Mat

Thanks!