终结例程是否需要是基本的才能在超出范围的可分配数组的元素上调用?

Does the finalization routine need to be elemental in order to be called on the elements of allocatable array that goes out of scope?

如果我有一个可终结派生类型的可分配数组,当数组超出范围时,是否会在每个单独的元素上调用终结器?

这里有一个小代码示例来说明问题:

module LeakyTypeModule

   implicit none
   private

   type, public :: LeakyType
      real, pointer :: dontLeakMe(:) => null()
   contains
      procedure :: New
      final     :: Finalizer
   end type

contains

   subroutine New(self, n)
      class(LeakyType), intent(out) :: self
      integer         , intent(in)  :: n
      allocate(self%dontLeakMe(n))
      self%dontLeakMe = 42.0
   end subroutine

   subroutine Finalizer(self)
      type(LeakyType), intent(inout) :: self
      if (associated(self%dontLeakMe)) deallocate(self%dontLeakMe)
   end subroutine

end module


program leak

   use LeakyTypeModule
   implicit none

   type(LeakyType), allocatable :: arr(:)

   allocate(arr(1))
   call arr(1)%New(1000)
   deallocate(arr)

end program

请注意,此程序泄漏了 LeakyTypeNew() 方法中分配的 dontLeakMe 数组。起初这让我有点惊讶,但后来我发现可以通过声明终结器 elemental 来解决这个问题。 gfortran 和 ifort 的行为方式相同,因此我假设此行为遵循 Fortran 2003 标准。

谁能证实这一点?老实说,我很难理解标准在这一点上所说的内容。

现在我也看不到在 not 中声明我所有的终结器元素有多大用处。这是否有任何我忽略的应用程序?

判断是否调用final procedure、调用哪个final procedure的规则与generic procedure的解析规则在rank matching要求上相同

注意到问题被标记为 Fortran 2003...

Fortran 2003 及更早版本中的基本过程必须是 PURE。如果你的终结器需要做一些与 pure 属性不兼容的事情(这很常见)那么终结器就不能是元素的,你需要编写特定于等级的变体。

Fortran 2008 引入了 IMPURE ELEMENTAL 的概念,这对于编写终结器非常方便。