Daily Agenda for Damian Rouson as of 5am
Damian Rouson
damian@rouson.net
Sun Dec 15 17:17:00 GMT 2013
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