fortran gfortran fortran2003

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.