Hello, I'm discovering the pleasures of the OOP and I'm faced with a problem depending on the compiler (ifort vs gfortran). Consider this first simple module:
module typedefs implicit none type base_t integer :: i = 0 end type base_t type, extends(base_t) :: ext1_t integer :: j = 0 contains procedure :: ext1EqCl generic :: assignment(=) => ext1EqCl end type ext1_t interface assignment(=) module procedure generic_assign end interface contains subroutine generic_assign (lhs, rhs) class(base_t), intent(in ) :: rhs class(base_t), intent(out), allocatable :: lhs print*,'--> generic_assign' allocate (lhs, source=rhs) end subroutine generic_assign subroutine ext1EqCl (lhs, rhs) class(base_t), intent(in ) :: rhs class(ext1_t), intent(out) :: lhs print*,'--> ext1EqCl' select type(rhs) type is (ext1_t) lhs%i = rhs%i ; lhs%j = rhs%j end select end subroutine ext1EqCl end module typedefs program test use typedefs implicit none class(base_t), allocatable :: p type(ext1_t) :: a1 print '(/,a)','*** do : a1 = ext1_t (1,2) ***' a1 = ext1_t (1,2) print '(/,a)','*** do : p = a1 ***' p = a1 print '(/,a)','*** do : a1 = p ***' a1 = p ; print*,'a1 =',a1 end program test
It compiles and works well with ifort, producing the obvious outputs:
*** do : a1 = ext1_t (1,2) ***
--> ext1EqCl
*** do : p = a1 ***
--> generic_assign
*** do : a1 = p ***
--> ext1EqCl
a1 = 1 2
But it doesn't compile with gfortran, producing the error: Ambiguous interfaces in intrinsic assignment operator for « generic_assign » at (1) and « ext1eqcl » at (2).
If I remove the generic assignment from ext1 and I add the procedure ext1EqCl in the assignment interface as in the following version of typedefs module:
module typedefs implicit none type base_t integer :: i = 0 end type base_t type, extends(base_t) :: ext1_t integer :: j = 0 end type ext1_t interface assignment(=) module procedure generic_assign module procedure ext1EqCl end interface contains subroutine generic_assign (lhs, rhs) class(base_t), intent(in ) :: rhs class(base_t), intent(out), allocatable :: lhs print*,'--> generic_assign' allocate (lhs, source=rhs) end subroutine generic_assign subroutine ext1EqCl (lhs, rhs) class(base_t), intent(in ) :: rhs type (ext1_t), intent(out) :: lhs print*,'--> ext1EqCl' select type(rhs) type is (ext1_t) lhs%i = rhs%i ; lhs%j = rhs%j end select end subroutine ext1EqCl end module typedefs
it compiles and works well with gfortran but not with ifort ( error #6745: The type/rank signature for the arguments of this specific subroutine matches another specific subroutine that shares the same defined ASSIGNMENT. [EXT1EQCL]).
Thank you very much for your time.
ps: ifort --version: ifort (IFORT) 15.0.3 20150408 gfortran --version: GNU Fortran (GCC) 6.3.0