The following test program attempts to perform something similar to Fortran's pack
intrinsics with a polymorphic derived type. In this example, the odd elements (1,3,5,7,9) of the 10-sized array are packed to positions (1:5). All assignments work besides the 1st element:
module assign
implicit none
private
type, public :: t
integer :: a
contains
procedure :: destroy=>t_destroy
procedure :: assign=>t_assign
generic :: assignment(=) =>assign
end type t
contains
elemental subroutine t_destroy(this)
class(t), intent(inout) :: this
this%a = 0
end subroutine t_destroy
subroutine t_assign(this,that)
class(t), intent(inout) :: this
class(t), intent(in) :: that
call this%destroy() ! Clean memory first
select type (thatPtr=>that)
type is (t)
this%a = thatPtr%a
end select
end subroutine t_assign
end module assign
program test
use assign
type(t), allocatable :: t1(:)
allocate(t1(10))
do i=1,10
t1(i)%a = i
end do
n = 0
do i=1,10
if (mod(i,2)/=0) then
n = n + 1
t1(n) = t1(i)
print *, 'i=',i,' t(i)%a=',t1(i)%a,' expected t(i)%a=',i,': ',merge('ERROR!','OK ',t1(i)%a/=i)
endif
end do
end program test
as the results are (note the first line):
i= 1 t(i)%a= 0 expected t(i)%a= 1 : ERROR!
i= 3 t(i)%a= 3 expected t(i)%a= 3 : OK
i= 5 t(i)%a= 5 expected t(i)%a= 5 : OK
i= 7 t(i)%a= 7 expected t(i)%a= 7 : OK
i= 9 t(i)%a= 9 expected t(i)%a= 9 : OK
My understanding is that, when running t(1) = t(1)
, the underlying code is call t_assign(t(1),t(1))
, which contains a call this%destroy()
, so t(1) is deleted before copying. I'm not confortable with this:
- Is this standard conforming behavior, or is the compiler (gfortran 10.2.0) just not catching the issue?
- It's my understanding that an assignment in Fortran with the equal sign would always create a temporary variable, is this not the case with the overloaded subroutines?
Thanks, Federico