fortran - ¿Por qué los nombres de los argumentos primordiales deben coincidir con los de la interfaz abstracta?
gfortran fortran2003 (1)
¿Por qué los nombres de los argumentos en los procedimientos de anulación deben coincidir con los de la interfaz abstracta?
Entiendo claramente que el TYPE
, INTENT
, etc. de dichos argumentos son necesarios para que coincida con la interfaz, pero ¿por qué el compilador se preocupa por lo que llamo mis variables?
A continuación, he definido una clase de utilidad abstracta simple que contiene un único procedimiento diferido EVAL
que toma un argumento de doble precisión.
!------------------------------------- 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
Definición de una clase de anulación y una implementación para 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
Recibo el siguiente error de gfortran
:
Error: El argumento ficticio ''otro_nombre_variable'' de ''eval'' en (1) debe llamarse ''datos'' para que coincida con el argumento correspondiente del procedimiento anulado
Si, en cambio, sustituyo DATA
por ANOTHER_VARIABLE_NAME
todo se compila y se ejecuta como se esperaba.
Pero esto me parece tonto. Deseo poder heredar desde FUNC_1D
varias veces, y bajo diversas circunstancias y me veo obligado a llamar a mis variables DATA
cada vez que me parece ridículo.
No entiendo por qué el compilador debería estar interesado en más que el TYPE
y la INTENT
de los argumentos?
Elaborando el comentario de High Performance Mark
No sé, pero sospecho que puede deberse a las capacidades de palabras clave del argumento de Fortran, lo que significa que puede llamar a su función de esta manera
fun_1d(data=the_data,this=that)
, es decir, puede nombrar los argumentos en la llamada en lugar de confiar en la coincidencia de posición.
considera lo siguiente
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
con las definiciones de procedimiento apropiadas con 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
Entonces despúes
class(func_1d), allocatable :: baz
allocate (foo_or_bar :: baz) ! For one of the types foo, bar
que, si tiene alguno, tiene sentido con una palabra clave de argumento?
print*, baz%eval(data=s)
print*, baz%eval(foo_var=s)
print*, baz%eval(bar_var=s)
[Hay casos en que esto sería mucho más pronunciado, especialmente con argumentos ficticios opcionales.]
El estándar requiere que guardes los mismos nombres de argumentos ficticios (es muy probable que evites el problema anterior). Ver 12.4.1 ISO / IEC 1539-1: 2010:
12.4.1 interfaz e interfaz abstracta
La interfaz de un procedimiento determina las formas de referencia a través de las cuales puede invocarse. La interfaz del procedimiento consiste en su nombre, etiqueta de enlace, identificadores genéricos, características y los nombres de sus argumentos ficticios. Las características y etiqueta de enlace de un procedimiento son fijas, pero el resto de la interfaz puede diferir en contextos diferentes, excepto que para un cuerpo de procedimiento de módulo separado (12.6.2.5), los nombres de argumentos ficticios y si es recursivo será el mismo como en su correspondiente cuerpo de interfaz separado (12.4.3.2).
Esto establece que los procedimientos separados que usan la misma interfaz deben tener los mismos nombres de argumentos ficticios que la interfaz. Esto se ve reforzado por 4.5.7.3:
Los procedimientos primordiales de tipo reemplazado y anulado deberán cumplir las siguientes condiciones.
- [...]
- Los argumentos ficticios que corresponden por posición tendrán los mismos nombres y características, excepto por el tipo de argumentos ficticios de objeto pasado.