c - promedio - fortran pdf
Diferentes parámetros numéricos que llaman a la rutina C de FORTRAN 90 (1)
Estoy llamando a una rutina C desde un código FORTRAN 90. Todo funciona bien, pero me pregunto por qué y cómo cuando llamo a la rutina C con menos parámetros de lo que debería el compilador no se queja. ¿Qué está haciendo el compilador aquí? Estoy usando un compilador de Cray.
test.c
extern "C" void test_(double* x, double* y, double* z){
// do some work
}
driver.F90
MODULE DRIVER
! declare arrays
DOUBLE PRECISION, DIMENSION(dim, dim), INTENT(IN) :: x
DOUBLE PRECISION, DIMENSION(dim, dim), INTENT(IN) :: y
! call C subroutine
CALL test(x, y)
END MODULE DRIVER
Fortran es muy diferente de C cuando se trata de llamadas a funciones. Al pasar argumentos a una rutina de C, el compilador debe conocer el tipo de cada argumento, de modo que pueda generar la secuencia de llamada apropiada: coloque los argumentos en la pila en el orden correcto y con el relleno correcto o póngalos en el orden esperado registros. Los compiladores de C suelen recopilar esta información cuando luego compilan el código si el destinatario se define antes que la persona que llama. En todos los demás casos, se debe proporcionar una declaración de función en forma de prototipo.
En Fortran todos los argumentos son típicamente (con algunas excepciones) pasados por la dirección, lo que significa que lo que realmente pasa al destinatario es un conjunto de punteros de memoria. Los indicadores tienen el mismo aspecto: siempre son del mismo tipo y, por lo tanto, se transmiten de la misma manera. Por lo tanto, un compilador Fortran puede generar una llamada a función sin saber qué argumentos realmente espera el destinatario. Esto simplifica en gran medida los compiladores Fortran, pero es una fuente de miríadas de posibles errores, como llamar a una función con los tipos de argumento incorrectos o incluso con el número incorrecto de argumentos, por nombrar algunos. Los programas especiales, denominados linters (del nombre de la lint
utilidad de verificación de los programas C), generalmente tienen que usarse para garantizar que no haya tales errores. Los compiladores Fortran modernos también intentan ser mucho más estrictos que los antiguos y hacen todo lo posible para detectar errores siempre que sea posible.
Las versiones modernas de Fortran proporcionan el constructo INTERFACE
que permite la declaración explícita de interfaces de funciones, muy similar a los prototipos de funciones en C. Las subrutinas y funciones del módulo obtienen sus interfaces generadas automáticamente y se ponen a disposición de las personas que USE
el módulo. Cuando se llama a una subrutina / función con una interfaz explícita, el compilador puede verificar la validez de la llamada, es decir, verifica si el número de argumentos y sus tipos coinciden con el de la interfaz.
Debería proporcionar una interfaz para la rutina externa y luego el compilador podría realizar las comprobaciones. Uno generalmente usa el método ISO_C_BINDING
para interactuar con el código C:
INTERFACE
SUBROUTINE test(x, y, z) BIND(C, NAME="test")
USE, INTRINSIC :: ISO_C_BINDING
REAL(KIND=C_DOUBLE), INTENT(...) :: x ! Put the proper intents
REAL(KIND=C_DOUBLE), INTENT(...) :: y
REAL(KIND=C_DOUBLE), INTENT(...) :: z
END SUBROUTINE test
END INTERFACE
Con esta interfaz en su lugar, la CALL test(x, y)
daría como resultado un error de tiempo de compilación debido a la discrepancia en el recuento de los argumentos.