Calling concrete type bound procedures on abstarct derived types

Calling concrete type bound procedures on abstarct derived types

A non-abstract subclass of an abstract type can call procedures on its abstract parent. But if the child overrides the parent procedure then it is no longer possible. I think there is no reason to have this restriction. Is there a way to overcome the compile errors without adding code to the parent type ?

Example:

module ParentType
implicit none
private
public Parent
type, abstract :: Parent
contains
procedure astractStuff
procedure doSomeStuff
end type
 
contains
subroutine astractStuff(item)
class(Parent), intent(inout) :: item
end subroutine
 
subroutine doSomeStuff(item)
class(Parent), intent(inout) :: item
end subroutine
 
end module
module ChildType
use ParentType
implicit none
type, extends(Parent) :: Child
contains
procedure :: doSomeStuff
end type
 
contains
subroutine doSomeStuff(item)
class(Child), intent(inout) :: item
call item%astractStuff() !OK to call non-overridden method in abstract type
call item%Parent%doSomeStuff() !Not OK when overridden
end subroutine
 
end module

The compile errors are:

1>D:\temp\Console1\Console1\Console1.f90(38): error #8314: If the rightmost part-name is of abstract type, data-ref shall be polymorphic [PARENT]1>D:\temp\Console1\Console1\Console1.f90(38): error #8422: If the component immediately preceding the type-bound procedure is abstract, the entire data reference before the procedure name must be polymorphic. [PARENT]

2 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.

The problem is that the term item%Parent attempts to reference a concept that doesn't exist - a non-polymorphic abstract object - an object that has a dynamic type of Parent.  Because the object is abstract, there is the potential for the bindings of the type to be incompletely specified (they are in your case - but in that case the parent doesn't need to be abstract).  You know that the specific binding that you are calling exists, but how about all the other bindings, that might subsequently be referenced as part of the problematic CALL?

The easy solution (and conceptually consistent to a degree) is to make the procedure that implements the binding in the parent type public, and then call it directly using a normal call statement (CALL procedure(object, ...), not the object%binding(...) syntax.  Because your extension is type compatible with the parent this should be straightforward.

In other cases you can split the parent type into a concrete grand-parent type and an abstract intermediate.  If you can't do this split - that highlights that the potential problem discussed in the first paragraph was real.

My view is that the syntax `object%binding` implies that you want to do dynamic type or object bound lookup of the procedure to call.  With the object%Parent%binding syntax you are not doing a dynamic lookup.  If you are not doing a dynamic lookup, then don't use the dynamic lookup syntax.  Issues around accessibility muddy this a little, but I still think this is the conceptually cleanest approach.

Kommentar hinterlassen

Bitte anmelden, um einen Kommentar hinzuzufügen. Sie sind noch nicht Mitglied? Jetzt teilnehmen