终止例程是否需要是元素才能被调用到超出范围的可分配数组元素上? [英] Does the finalization routine need to be elemental in order to be called on the elements of allocatable array that goes out of scope?

查看:142
本文介绍了终止例程是否需要是元素才能被调用到超出范围的可分配数组元素上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这是示例问题的小代码示例:

  module LeakyTypeModule 

隐式无
私有

type,public :: LeakyType
real,pointer :: dontLeakMe(:) => null()
包含
过程::新建
final ::终结符
结束类型

包含

子程序新建( self,n)
class(LeakyType),intent(out):: self
整数,intent(in):: n
allocate(self%dontLeakMe(n))
self(自我)
type(LeakyType),intent(inout):: self
if(associated(self(% dontLeakMe))deallocate(self%dontLeakMe)
结束子程序

结束模块


程序泄漏

使用LeakyTypeModule
隐式无

类型(LeakyType),allocatable :: arr(:)

allocate(arr(1))
call arr(1)%新(1000)
解除分配(arr)

结束程序

请注意,此程序泄漏 New()方法中分配的 dontLeakMe 数组 LeakyType 。起初,这对我来说有点令人惊讶,但是,后来我发现可以通过声明终结器 elemental 来解决问题。 gfortran和ifort的行为都是一样的,所以我假设这种行为遵循Fortran 2003标准。



任何人都可以证实这一点吗?说实话,我很难理解标准在这个特定点上所说的话。



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

解决方案

确定是否调用最终过程的规则以及哪个最终过程被调用,与通用过程的排名匹配要求相同。

b
$ b

Fortran 2003和之前的元素过程必须是PURE。如果你的finalizer需要做一些与pure属性不相容的东西(这是相当常见的),那么finalizer不能是元素,你需要编写特定等级的变体。



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


If I have an allocatable array of a finalizable derived type, will the finalizer be called on every individual element when the array goes out of scope?

Here is a small code example that illustrates the question:

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

Note that this program leaks the dontLeakMe array allocated in the New() method of LeakyType. At first this was a bit surprising for me but, then I discovered that the problem can be fixed by declaring the finalizer elemental. Both gfortran and ifort behave in the same way, so I assume this behaviour is following the Fortran 2003 standard.

Can anyone confirm this? To be honest I have a hard time time understanding what the standard says on this particular point.

Right now I also can't see much use in not declaring all my finalizers elemental. Does this have any application I'm overlooking?

解决方案

The rules for determining whether a final procedure is invoked, and which final procedure is invoked, are the same as for resolution of generic procedures in terms of rank matching requirements.

Noting that the question is tagged Fortran 2003...

Elemental procedures in Fortran 2003 and prior have to be PURE. If your finalizer needs to do something that is incompatible with the pure attribute (which is reasonably common) then the finalizer cannot be elemental, and you need to write the rank specific variants.

Fortran 2008 introduces the concept of IMPURE ELEMENTAL, which is quite handy for writing finalizers.

这篇关于终止例程是否需要是元素才能被调用到超出范围的可分配数组元素上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆