Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28447 Discussions

generic operator with class(*) behavior question

Patrice_l_
Beginner
444 Views

Hi,

I am wondering how does the generic operator works in case of an abstract class with a class(*) argument. The following code show an example, and the operator on the abstract class do not call the defined operator of intb even though the dynamic type is intb.  Any thought on such design ? A solution will be to override lower_than in intb like that rocedure,private :: lower_than => lowerthan_intb with a class(*) and then do a select type. But i thought that if the dynamic type was intb then the generic function will find lowerthan_intb.

 

 

module tata
implicit none

type,abstract :: b_type
        class(*),allocatable :: b
        contains
                procedure,private :: lower_than
                generic,public :: operator(.lt.) => lower_than
end type

        type,extends(b_type) :: intb 
        contains
                procedure,private :: lowerthan_intb
                generic,public :: operator(.lt.) => lowerthan_intb
        end type
        interface intb
                module procedure :: intb_constructor
        end interface
contains
function intb_constructor(i) result(a)
        type(intb) :: a
        integer :: i
        allocate(a%b,source=i)
end function        
function lowerthan_intb(a,b) result(r)
        class(intb),intent(in) :: a,b
        logical :: r
        print *,'lowerthan intb'
        select type(i1 => a%b)
        type is(integer)
                select type(i2 => b%b)
                type is(integer)
                        r=i1<i2
                end select
        end select
end function
function lower_than(a,b)
        class(b_type),intent(in) :: a
        class(*),intent(in) :: b
        logical :: lower_than
        lower_than=.false.
        print *, 'operator lower than class* no implementation' 
end function


end module

program foo
use tata
implicit none
type(intb) :: d,d2
class(intb),allocatable :: cd,cd2
class(b_type),allocatable :: b1,b2

d=intb(1)
d2=intb(3)
allocate(cd,source=d)        
allocate(cd2,source=d2)       
print *,d<d2 
allocate(b1,source=cd)
allocate(b2,source=cd2)
print *,'b1 extends btype to intb',extends_type_of(b1,d),same_type_as(b1,d)
print *,b1.lt.b2 
print *,b1<b2 
print *, cd<b1


end program 

 

0 Kudos
5 Replies
Patrice_l_
Beginner
444 Views

Should the compiler gives an ambiguous error in this case ? (gfortran does).

Also , what is the answer to extends_type_of(b1,d),same_type_as(b1,d), ifort says  T T, but gfortran says F T. Since the dynamic type is the same i think it should be true.

0 Kudos
FortranFan
Honored Contributor II
444 Views

Patrice l. wrote:

Should the compiler gives an ambiguous error in this case ? (gfortran does).

I think so, my read of the Fortran 2008 standard suggests your lower_than and lower_than_intb do not satisfy the generic disambiguation rules:

bad6.png

0 Kudos
Patrice_l_
Beginner
444 Views

I agree with your reading FortranFan, since it will match class(*) and class(intb) at the same time. Then do you agree that extends_type_of(b1,d) should return T ?

0 Kudos
FortranFan
Honored Contributor II
444 Views

Patrice l. wrote:

I agree with your reading FortranFan, since it will match class(*) and class(intb) at the same time. Then do you agree that extends_type_of(b1,d) should return T ?

Yes, I think extends_type_of(b1,d) must return true based on what the standard says:

ext_f.png

ext.png

Looking at the definition of extension type (same type or an extended type), the result should be true, I think.

 

0 Kudos
Steven_L_Intel1
Employee
444 Views

I have escalated the missing error about ambiguous interface as issue DPD200371156.

0 Kudos
Reply