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

SELECT TYPE confusion

OP1
新分销商 III
773 次查看

The confusion is either the compiler's or mine...

The following code produces two different outputs for the lines 23 and 24, and I am not sure I understand why. Anybody cares to chime in? This is with ifort classic 2021.5.0 on Windows, x64.

MODULE M
IMPLICIT NONE
TYPE :: T
    CONTAINS
        PROCEDURE P
END TYPE T
TYPE, EXTENDS(T) :: TT
    CONTAINS
        PROCEDURE PP
END TYPE TT
CONTAINS
SUBROUTINE P(SELF)
CLASS(T) :: SELF
SELECT TYPE (SELF)
    TYPE IS (T)
        WRITE(*, *) 'T'
    TYPE IS (TT)
        WRITE(*, *) 'TT'
END SELECT
END SUBROUTINE P
SUBROUTINE PP(SELF)
CLASS(TT) :: SELF
CALL SELF%T%P ! This produces 'T'
CALL SELF%P   ! This produces 'TT'
END SUBROUTINE PP
END MODULE M

PROGRAM P
USE M
IMPLICIT NONE
TYPE(TT) :: VAR
CALL VAR%PP
END PROGRAM P
0 项奖励
4 回复数
FortranFan
名誉分销商 III
744 次查看

Can you elaborate on your confusion?

The standard explains it is the dynamic type of the object in question that governs the branching in the `SELECT TYPE` construct: "The selection is based on the dynamic type of an expression."

As such, the program using IFORT indeed appears conformant with the standard.

0 项奖励
OP1
新分销商 III
720 次查看

ok, so it seems that (in pseudo-code) what happens on line 23 is akin to CALL (SELF%T)%P, that is, the dynamic type of the passed object in P is T.

My expectation was that, instead, the call was doing something akin to CALL SELF%(T%P), that is, pass an object of dynamic type TT to the procedure P that is type-bound to T.

I have to admit that this feels a bit strange!

0 项奖励
IanH
名誉分销商 III
684 次查看

@OP1 wrote:

...

My expectation was that, instead, the call was doing something akin to CALL SELF%(T%P), that is, pass an object of dynamic type TT to the procedure P that is type-bound to T.


Syntax for that is simply:

CALL P(SELF)

You can statically identify the procedure that you want to invoke, so there's no need to reference it through a dynamically dispatched binding (namespace management aspects of bindings aside).

0 项奖励
FortranFan
名誉分销商 III
661 次查看

When the parent type component of an extended type can be referenced e.g., when the parent type is not an abstract type, you can view the parent type reference - such as with SELF%T in your code snippet - as having the dynamic type to be the same as its declared type which in your case is 'T'.

 

So, in effect, whether your instruction is `CALL SELF%T%P` or `CALL P( SELF%T )`, the effective argument to the procedure P will be of TYPE of 'T'.

0 项奖励
回复