问题
Why do the names of arguments in overriding procedures need to match those of the abstract interface?
I understand that clearly the TYPE
, INTENT
, etc of such arguments are required to match the interface, but why should the compiler care what I call my variables?
In the following, I've defined a simple abstract utility class containing a single deferred procedure EVAL
that takes a double precision argument.
!------------------------------------- an abstract utility class !
type, abstract :: func_1d
contains
procedure(interface_1d),deferred :: eval
end type func_1d
!-------------------------------------------- interface for eval !
abstract interface
function interface_1d(this,data) result(rval)
import :: func_1d
class(func_1d), intent(inout) :: this
real*8 , intent(in) :: data
real*8 :: rval
end function interface_1d
end interface
Defining an overriding class and an implementation for EVAL
:
type, extends(func_1d) :: foo
contains
procedure, pass :: eval => eval_foo
end type foo
function eval_foo(this,another_variable_name) result(rval)
implicit none
class(foo), intent(inout) :: this
real*8, intent(in) :: another_variable_name
real*8 :: rval
!! etc
end function eval_foo
I get the following error from gfortran
:
Error: Dummy argument 'another_variable_name' of 'eval' at (1) should be named 'data' as to match the corresponding argument of the overridden procedure
If I instead substitute DATA
for ANOTHER_VARIABLE_NAME
everything compiles and runs as expected.
But this seems silly to me. I want to be able to inherit from FUNC_1D
multiple times, and under various circumstances and being forced to call my variables DATA
every time seems ridiculous.
I don't understand why the compiler should be interested in more than the TYPE
and INTENT
of the arguments?
回答1:
Elaborating on High Performance Mark's comment
I don't know but I suspect that it may be down to Fortran's argument keyword capabilities, which mean that you can call your function like this
fun_1d(data=the_data,this=that)
, that is you can name the arguments in the call rather than rely on position matching.
consider the following
type, extends(func_1d) :: foo
contains
procedure, pass :: eval => eval_foo
end type foo
type, extends(func_1d) :: bar
contains
procedure, pass :: eval => eval_bar
end type bar
with appropriate procedure definitions with interfaces
real*8 function eval_foo(this,foo_var)
class(foo), intent(inout) :: this
real*8, intent(in) :: foo_var
end function
real*8 function eval_bar(this,bar_var)
class(bar), intent(inout) :: this
real*8, intent(in) :: bar_var
end function
then later
class(func_1d), allocatable :: baz
allocate (foo_or_bar :: baz) ! For one of the types foo, bar
which, if any, makes sense with an argument keyword?
print*, baz%eval(data=s)
print*, baz%eval(foo_var=s)
print*, baz%eval(bar_var=s)
[There are cases where this would be much more pronounced, especially with optional dummy arguments.]
The standard requires that you keep the same dummy argument names (very likely to avoid the issue above). See 12.4.1 ISO/IEC 1539-1:2010:
12.4.1 Interface and abstract interface
The interface of a procedure determines the forms of reference through which it may be invoked. The procedure’s interface consists of its name, binding label, generic identifiers, characteristics, and the names of its dummy arguments. The characteristics and binding label of a procedure are fixed, but the remainder of the interface may differ in differing contexts, except that for a separate module procedure body (12.6.2.5), the dummy argument names and whether it is recursive shall be the same as in its corresponding separate interface body (12.4.3.2).
This states that separate procedures using the same interface shall have the same dummy argument names as the interface. This is further strengthened by 4.5.7.3:
The overriding and overridden type-bound procedures shall satisfy the following conditions.
- [...]
- Dummy arguments that correspond by position shall have the same names and characteristics, except for the type of the passed-object dummy arguments.
来源:https://stackoverflow.com/questions/29011920/why-do-the-names-of-overriding-arguments-have-to-match-those-of-the-abstract-int