- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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'.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page