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

Class(*) and overriding binding

abhimodak
New Contributor I
928 Views
Hi

Since Class(*) is type compatible with any type, can it be used in a binding which gets overridden by a binding with specific type?

The snippet below gives compile-time error with IVF 12 update 1. (With use of Class(*) in subroutine Tech it works as expected.) I don't get an error with XLFortran but I am not 100% sure if it is right.

A similar question can also be asked for a procedure pointer component. That is, in the definition of type the interface of the procedure pointer is given Class(*) and when it is used (points to other procedure) some other type is used. (IVF 12 gives an error for this case as well.)

Abhi
------------


[fortran]      Module OM
         Implicit None
         Private
         Type newBase
            Integer :: i
         Contains
            Procedure, NoPass :: Method
            Procedure :: Calculate
         End Type newBase
         Public :: newBase
      Contains
         Subroutine Method(other, n)
            Class(*), Intent(IN) :: other
            Integer,  Intent(IN) :: n
            print *, n
         End Subroutine Method
         Subroutine Calculate(OBJ, other, n)
            Class(newBase), Intent(IN) :: OBJ
            Class(*), Intent(IN) :: other
            Integer,  Intent(IN) :: n
            Call OBJ%Method(other, n)
         End Subroutine Calculate
      End Module OM
      
      Module Shree
         Use OM
         Implicit None
         Private
         Type newModel
            Real :: r
         Contains
            Procedure :: Compute
         End Type newModel
         Type, Extends(newBase) :: newExt
         Contains
            Procedure, NoPass :: Method => Tech
         End Type newExt
         Type(newExt) :: EXT
         Public :: newModel
      Contains
         Subroutine Tech(other, n)
            Class(newModel), Intent(IN) :: other
            !Class(*), Intent(IN) :: other
            Integer, Intent(IN) :: n
            Print *, n+1
         End Subroutine Tech
         Subroutine Compute(Model)
            Class(newModel), Intent(IN) :: Model
            Integer :: m
            m = -1
            Call EXT%Calculate(Model, m)
         End Subroutine Compute
      End Module Shree
      
      Program Test_Polymorphic
         Use Shree
         Implicit None
         Type(newModel) :: Model
         Call Model%Compute()
      End Program Test_Polymorphic[/fortran]
0 Kudos
5 Replies
Steven_L_Intel1
Employee
928 Views
I think this is the same as a previously reported issue, ID DPD200163706. Did you really mean to say Class(newModel) and not Class(newExt)? You do the override in the declaration of newExt, so it would be incorrect to have something of type or class newModel as the "passed-object dummy argument".
0 Kudos
abhimodak
New Contributor I
928 Views
Hi Steve

Thanks. I should have added the reference to the post you mentioned. I had read it but perceived it to be slightly different.

Note that the procedure Method is "NoPass" and thus there is no pass-object dummy. I am overriding by passing Class(newModel) and not Class(newExt). I think that is still correct since the corresponding argument is Class(*).

Also, will it be the same case with procedure pointer component? The sample program is given below.

{The ultimate goal is to pass the type bound procedure of Model to Base. The desired usage is to allow another subroutine in Base (such as Calculate in the overriding example) to call procedures that differ only by one argument corresponding to the "class" such as newModel.}

Abhi

---

[fortran]      Module OM
         Implicit None
         Type newBase
            Integer :: i
            Procedure(FUN), Pointer, NoPass :: Method
         End Type newBase
         Abstract Interface
            Subroutine FUN(OBJ, n)
               Class(*), Intent(IN) :: OBJ
               Integer,  Intent(IN) :: n
            End Subroutine FUN
         End Interface
      End Module OM

      Module Shree
         Use OM
         Implicit None
         Type newModel
            Real :: r
         Contains
            Procedure :: Compute
            Procedure :: Tech
         End Type newModel
      Contains
         Subroutine Compute(Model)
            Class(newModel), Intent(INOUT) :: Model
            Integer :: m
            Type(newBase) :: Base
            Base%Method => Tech
         End Subroutine Compute
         Subroutine Tech(Model, j)
            Class(newModel), Intent(INOUT) :: Model
            !Class(*), Intent(INOUT) :: Model
            Integer, Intent(IN) :: j
         End Subroutine Tech
      End Module Shree

      Program Test_ProcedurePointer

         Use Shree
         Implicit None

      End Program Test_ProcedurePointer

[/fortran]

0 Kudos
Steven_L_Intel1
Employee
928 Views
Ah, I had missed that. The standard requires that all dummy arguments of the overriding and overridden procedures, other than the passed-object, match in name and characteristics, including type.
0 Kudos
Steven_L_Intel1
Employee
928 Views
The problem with compiling the first code shown in this thread has been fixed in 12.0 Update 3. The second code is incorrect.
0 Kudos
Steven_L_Intel1
Employee
928 Views

We've been looking at this issue again. While it is true that class(*) is type-compatible with any type, that doesn't mean it is "the same as" any other type. Indeed, the standard says that entities of class(*) have no type at all. In the context of overrides, if one of the dummies is class(*) they all must be. We're going to correct the compiler to give an error where this is not the case.

0 Kudos
Reply