Quantcast
Channel: Intel® Fortran Compiler for Linux* and macOS*
Viewing all articles
Browse latest Browse all 2583

polymorphic variables: assignment "poly = a" and "a = poly"

$
0
0

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

 

 

 


Viewing all articles
Browse latest Browse all 2583

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>