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

Problem with overridng an abstract type

Jens_B__Helmers
Beginner
1,148 Views
I'm starting to play with abstract types and ivf-2011.8.278 on win7. What is wrong with the dummy arguments for v2v as defined in line 24? The error message from the compiler is given below the code. As far as I understand there seems to be a match of characteristics between the interface defined in vec_def and vec2d_def. Any help on this would be appreciated.

Kind regards,
Jens B. Helmers

[bash]module vec_def
implicit none
type, abstract :: vec
contains
    procedure(fun), deferred :: v2v
    generic :: assignment(=) => v2v
end type vec
abstract interface
    subroutine fun(a, b)
        import :: vec
        class(vec), intent(out) :: a
        class(vec), intent(in)  :: b
    end subroutine fun
end interface
end module vec_def


module vec2d_def
use vec_def, only: vec
implicit none
type, extends(vec) :: vec2d
    real :: x, y
contains
    procedure :: v2v
end type vec2d
contains
    subroutine v2v(a, b)
        class(vec2d), intent(out) :: a
        class(vec2d), intent(in)  :: b
        a%x = b%x
        a%y = b%y
    end subroutine v2v
end module vec2d_def
[/bash]
error #8383: The dummy arguments of an overriding and overridden binding that correspond by position must have the same characteristics, except for the type of the passed object dummy arguments. [V2V]
0 Kudos
1 Reply
IanH
Honored Contributor III
1,148 Views
The b dummy argument in v2v has a declared type of vec2d. To match the abstract interface it should have a declared type of vec.

(A binding that overrides a binding in its parent type can only have a different type for the passed argument - the passed argument needs to be the same type as the type that is overriding the binding. All other arguments need to have the same characteristics. In the absence of a NOPASS or PASS clause on the binding to the contrary, the default is that the first argument is the passed argument.)

Conceptually, consider that the binding in the parent type is for a subroutine that takes an argument (b) of type that is of any extension of vec and copies its contents across to an argument that is of the type hosting the binding. Your binding in vec2d_def is more restrictive than that - you exclude the possibility of actual arguments of b that are extensions of vec other than vec2d.

(What you are trying to do is to specify that argument "a" and argument "b" are of the same type, but the language doesn't have that concept/capability.)

The v2v subroutine in module vec2d_def could perhaps be written something like:
[bash]subroutine v2v(a, b)
  class(vec2d), intent(out) :: a
  class(vec), intent(in) :: b
  select type (b)
  class is (vec2d)
    a%x = b%x
    a%y = b%y
  class default
    stop "Argument b to v2v in module vec2d_def has the wrong dynamic type"
  end select
end subroutine v2v[/bash]
Perhaps you could replace the stop statement with sensible default behaviour.

Note that a simple value assignment between polymorphic objects can be achieved in F2003 with an allocate(..., source=...) statement (supported (sans bugs) in ifort 12.1.2) , and in F2008 with an assignment statement (not in ifort 12.1).
0 Kudos
Reply