Question about finalization of abstract types
Damian Rouson
damian@rouson.net
Sun Dec 15 17:19:00 GMT 2013
I’m resending with the correct “Subject” line (as I’m sure no one is interested in my daily agenda!).
:D
Begin forwarded message:
> From: Damian Rouson <damian@rouson.net>
> Subject: Re: Daily Agenda for Damian Rouson as of 5am
> Date: December 15, 2013 at 9:17:16 AM PST
> To: fortran@gcc.gnu.org
> Cc: abenson@obs.carnegiescience.edu
>
> Hi Andrew,
>
> I think the code is invalid based on the Fortran 2008 standard Section 4.5.6 Final subroutines:
>
> * C480 (R452) A final-subroutine-name shall be the name of a module procedure with exactly one dummy argument. That argument shall be nonoptional and shall be a nonpointer, nonallocatable, nonpolymorphic variable of the derived type being defined...
>
> The nonpolymorphic requirement implies that the named type cannot be abstract.
>
> An abstract type can, however, have a finalizable component. Instead of having a pointer in the abstract, why not have finalizable component that itself has a pointer component? Here’s what I recommend:
>
>
> module test
> implicit none
>
> ! This should be more predictable & portable than “double precision”:
> integer, parameter :: dp = selected_real_kind(15, 307)
>
> type finalizable
> ! Give the pointer default initialization to null so it doesn’t start life out in an undefined state:
> real(dp), pointer :: d=>null()
> contains
> final :: finalizableTypeDestructor
> end type
>
> type, abstract :: testType
> type(finalizable) :: something
> end type testType
>
> contains
>
> subroutine finalizableTypeDestructor(self)
> type(finalizable), intent(inout) :: self
> if (associated(self%d)) deallocate(self%d)
> ! There is no need for a “return” statement at the end of a subroutine or function
> end subroutine
>
> end module test
>
>
> I have corresponded with at least six compiler teams on this subject and all concluded that an abstract type with a finalizable component is acceptable. Of the six, I think gfortran is the only one that won’t yet finalize the component (although it does accept the syntax). I think Tobias has worked on supporting finalization in the above case so hopefully he can give us an update on the status. It would be great for you to add your voice in support of the need for this work. :)
>
> Now for a safety note: if you’re going to write a line like
>
> if (associated(self%d)) deallocate(self%d)
>
> then I very strongly urge you to adopt a strategy that will prevent dangling pointers. If self%d is associated, are you certain that the association is unique? If there are other pointers associated with that same object, you’ll have “dangling pointers.” Such scenarios can be a nightmare to debug and there’s a whole cottage industry around detecting such pointer-related problems in C/C++.
>
> If the association is unique, then why not replace the “pointer” attribute with the “allocatable” attribute? I would guess that most compilers implement allocatable objects “under the hood” as single-association pointers. The big advantage is you’ll never have to write final subroutine because the compiler will free the memory for you when the associated name goes out of scope.
>
> Lastly, if for some reason you really do need “pointer” rather than “allocatable,” then I strongly encourage adopting a reference-counting strategy so that you only free the memory once there are no more pointers associated with it. For an example of such a strategy, see http://www.computer.org/csdl/mags/cs/2012/02/mcs2012020046-abs.html.
>
>
> Damian
> http://rouson.net
>
>
More information about the Fortran
mailing list