Hi all,
I noticed that when arrays of derived types are allocated in an (ordinary) way, no finalization is invoked at deallocation. Here is an example:
Module mod_tmp1 Type :: tmp1 Real, allocatable :: a(:,:) contains Final :: SubFinalizer end type tmp1 Type tmp2 type(tmp1), allocatable :: x end type tmp2 contains Subroutine SubFinalizer(this) Implicit none Type(tmp1), Intent(InOut) :: this write(*,*) "finalizer called" End Subroutine SubFinalizer End Module mod_tmp1 Program Test use Mod_tmp1 Type(tmp1), allocatable :: a,b(:) type(tmp2), allocatable :: c(:) integer :: i allocate(a,b(1),c(1)) allocate(c(1)%x) write(*,*) "deallocate a" deallocate(a) write(*,*) "deallocate b" deallocate(b) write(*,*) "deallocate c" deallocate(c) End Program Test
with the output
deallocate a finalizer called deallocate b deallocate c finalizer called
Is this behavior is observed with ifort 19.04 and gfortran 9.1. I couldn't really find something in standard 2008 which rules out the finalization of "b".
Any idea?
Thanks
Link Copied
may.ka wrote:.. I couldn't really find something in standard 2008 which rules out the finalization of "b".
Any idea? ..
The shown implementation(SubFinalizer) in the original post for the 'final' generic only covers the rank-0 (scalar) attribute of an object to be finalized, one has to implement specific procedures for each rank that is to be supported for finalization, or consider the ELEMENTAL attribute for the final subroutine:
module mod_tmp1 implicit none type :: tmp1 real, allocatable :: a(:,:) contains final :: SubFinalizer end type tmp1 type tmp2 type(tmp1), allocatable :: x end type tmp2 contains impure elemental subroutine SubFinalizer(this) !<-- IMPURE only because of WRITE statement in the scope type(tmp1), intent(inout) :: this write(*,*) "finalizer called" end subroutine SubFinalizer end module mod_tmp1 program Test use Mod_tmp1 type(tmp1), allocatable :: a,b(:) type(tmp2), allocatable :: c(:) integer :: i allocate(a,b(1),c(1)) allocate(c(1)%x) write(*,*) "deallocate a" deallocate(a) write(*,*) "deallocate b" deallocate(b) write(*,*) "deallocate c" deallocate(c) end program Test
Upon execution,
deallocate a finalizer called deallocate b finalizer called deallocate c finalizer called
may.ka wrote:.. I couldn't really find something in standard 2008 which rules out the finalization of "b".
Any idea? ..
The shown implementation(SubFinalizer) in the original post for the 'final' generic only covers the rank-0 (scalar) attribute of an object to be finalized, one has to implement specific procedures for each rank that is to be supported for finalization, or consider the ELEMENTAL attribute for the final subroutine:
module mod_tmp1 implicit none type :: tmp1 real, allocatable :: a(:,:) contains final :: SubFinalizer end type tmp1 type tmp2 type(tmp1), allocatable :: x end type tmp2 contains impure elemental subroutine SubFinalizer(this) !<-- IMPURE only because of WRITE statement in the scope type(tmp1), intent(inout) :: this write(*,*) "finalizer called" end subroutine SubFinalizer end module mod_tmp1 program Test use Mod_tmp1 type(tmp1), allocatable :: a,b(:) type(tmp2), allocatable :: c(:) integer :: i allocate(a,b(1),c(1)) allocate(c(1)%x) write(*,*) "deallocate a" deallocate(a) write(*,*) "deallocate b" deallocate(b) write(*,*) "deallocate c" deallocate(c) end program Test
Upon execution,
deallocate a finalizer called deallocate b finalizer called deallocate c finalizer called
Hi,
thanks.
Regards
For more complete information about compiler optimizations, see our Optimization Notice.