Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
554 views
in Technique[技术] by (71.8m points)

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

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...