- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This might seem like a strange thing to do, but what I am trying to achieve is to extend (instead of just overriding) a type bound procedure. The attached code does this but if the parent type is made abstract then I get:
ifort call_overridden.f90
call_overridden.f90(28): error #8314: If the rightmost part-name is of abstract type, data-ref shall be polymorphic [PARENT]
call self%parent%proc
----------------^
call_overridden.f90(28): 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]
call self%parent%proc
----------------^
compilation aborted for call_overridden.f90 (code 1)
This article about error #8307 gives two possible solutions. The first is to make the procedure "nonoverridden" which is obviously contrary to what I'm trying to achieve and I can't make sense of the second. Is there a way to do what I'm try to do or should I go about this in a different way?
ifort call_overridden.f90
call_overridden.f90(28): error #8314: If the rightmost part-name is of abstract type, data-ref shall be polymorphic [PARENT]
call self%parent%proc
----------------^
call_overridden.f90(28): 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]
call self%parent%proc
----------------^
compilation aborted for call_overridden.f90 (code 1)
This article about error #8307 gives two possible solutions. The first is to make the procedure "nonoverridden" which is obviously contrary to what I'm trying to achieve and I can't make sense of the second. Is there a way to do what I'm try to do or should I go about this in a different way?
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do not understand your stipulations.
In the first sentence you say you wish to extend instead of override. In the penultimate sentence you reject a solution that does not allow overriding.
And, since type child in your code has a component proc identical in name to that of the parent type parent that it extends, overriding must occur. What gives?
Rather than parsing the error messages from the compiler, it would be helpful if we could make the requirements clear.
In the first sentence you say you wish to extend instead of override. In the penultimate sentence you reject a solution that does not allow overriding.
And, since type child in your code has a component proc identical in name to that of the parent type parent that it extends, overriding must occur. What gives?
Rather than parsing the error messages from the compiler, it would be helpful if we could make the requirements clear.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I guess the OP is referring to the behavior of "complements" instead of "overrides", in regards to abstract types. As the OP's example shows, if the parent type is non-abstract, its implementation of proc can still be accessed through the %parent% component (which is analogous to Java's "super" keyword), and therefore the procedure defined in the extended type complements that of the parent type. As an example, consider the following code:
[fortran]module mod1 implicit none type :: t1 integer :: a, b contains procedure :: square => square_t1 end type type, extends(t1) :: t2 integer :: c contains procedure :: square => square_t2 end type contains integer function square_t1(this) result(sq) class(t1), intent(IN) :: this sq = this%a ** 2 + this%b ** 2 end function integer function square_t2(this) result(sq) class(t2), intent(IN) :: this sq = this%t1%square() + this%c ** 2 end function end module mod1 program test use mod1 implicit none type(t1) :: x = t1(2, 3) type(t2) :: y = t2(2, 3, 4) print '("t1%square() = ", I0)', x%square() print '("t2%square() = ", I0)', y%square() end program test[/fortran]
The new "square" procedure doesn't need to be a re-implementation, but simply a complement to the "square" procedure in the parent type.
It seems that in Fortran, such thing is not possible if the parent type is abstract ---I'm not sure either if other programming languages allow it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I see. Thanks. Perhaps the O.P. can expand on his intentions a little more clearly.
Here is another version of your example, but using an abstract type.
If, in the main program tst, the variable c is initialized using the declaration
Here is another version of your example, but using an abstract type.
[fortran]module test_modThe Intel compiler compiles this fine, and the answer is as expected; however, with the parentheses left out on line-33, the Intel compiler w_cprof_p_11.1.065 dies with an ICE.
implicit none
type, abstract :: atype
integer :: x, y
end type atype
type, extends(atype) :: btype
contains
procedure :: proc => sqp
end type btype
type, extends(btype) :: ctype
integer :: z
contains
procedure :: proc => sqc
end type ctype
contains
integer function sqp(self)
implicit none
class(btype) :: self
sqp = self%x**2 + self%y**2
end function sqp
integer function sqc(self)
implicit none
class(ctype) :: self
sqc = self%btype%proc() + self%z**2 !leaving out () cause ICE
end function sqc
end module test_mod
program test
use test_mod
implicit none
type(ctype) :: c
c%x = 2; c%y = 3; c%z = 4;
write(*,*)' x^2 + y^2 + z^2 = ',c%proc()
end program test[/fortran]
If, in the main program tst, the variable c is initialized using the declaration
[fortran] type(ctype) :: c = ctype(2, 3, 4) [/fortran]the compiler gives the confusing error message
[bash]error #8212: Omitted field is not initialized. Field initialization missing:[/bash]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Apologies if my post was not clear and thank you for your clarification John. Yes the point is that, if the parent type is abstract, it is not possible to get the desired behaviour, however this post indicates that it is not clear whether or not this should be the case under the standard.
Mecej4, I get the ICE you do with the latest beta of the compiler. A similar bug was reported here but, as you point out, it has been fixed. It seems that the difference in this case is that the procedure is not external.
Mecej4, I get the ICE you do with the latest beta of the compiler. A similar bug was reported here but, as you point out, it has been fixed. It seems that the difference in this case is that the procedure is not external.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page