I noticed a strange linking error with gfortran (GNU Fortran (Debian 4.9.2-10) 4.9.2) that depends on the order in which I define members in a derived type. With ifort (ifort (IFORT) 18.0.1 20171018), the code compiles and behaves as expected.
module bug
implicit none
type indestructable
integer :: i
end type
type destructable
integer :: i
contains
final :: destruct
end type destructable
type compound
type(destructable) :: des
type(indestructable) :: ind
end type compound
contains
subroutine destruct(instance)
type(destructable), intent(in) :: instance
write(*,*) instance%i
end subroutine destruct
subroutine run
type(compound) :: cmp
cmp%des%i = 3
cmp%ind%i = 4
end subroutine run
end module bug
program main
use bug, only: run
implicit none
call run
end program main
This program should print out '3' on finalization, because the 'des' in 'cmp' has a destructor that writes out its member 'i', which was set to 3.
In gfortran, the compiler gives an error that the destructor of type compound is not defined. This destructor should be automatically generated and call the destructors of all the members. The problem is that there is also a member of a type without destructor in the compound type. And this somehow hampers gfortran with the organization of the destructors.
This issue is solved by putting the destructable member after the indestructable member (switching the two lines inside the type definition of compound).
Does anyone know if this is a compiler issue that may be solved in later versions, or am I doing something wrong and ifort somehow fixes it for me. I always learned that the order in which member variables are defined should not matter.
For anyone encountering the same problem: "Always put your destructable members at the end". However, non-derived types do not seem to matter, even if they are allocatable.