resueltos programas programación problemas ejemplos descargar comandos fortran fortran90

programas - Lanzar un error si alguna interfaz de procedimiento no está explícitamente definida, o en un módulo en Fortran 90+



problemas resueltos de programación en fortran 95 pdf (2)

En el artículo Errores en Fortran 90 Programas que podrían sorprenderte

Esta es la siguiente sección,

Peligro de llamar rutinas de estilo Fortran 90

program main real, dimension(5) :: x x = 0. ! THIS IS WRONG call incb(x) print *, x end program main subroutine incb(a) ! this is a fortran90 style subroutine real, dimension(:) :: a a = a + 1. end subroutine incb

Explicación La subrutina incb utiliza una matriz de formas asumida estilo Fortran 90 (que contiene la dimensión (:)). Dichas rutinas deben estar en un módulo o tener una interfaz explícita dondequiera que se utilicen. En este ejemplo, ninguno fue verdadero.

Una forma correcta de llamar a dichos procedimientos es utilizar una interfaz explícita de la siguiente manera:

program main real, dimension(5) :: x ! THIS IS THE RIGHT WAY interface subroutine incb(a) real, dimension(:) :: a end subroutine incb end interface x = 0. call incb(x) print *, x end program main subroutine incb(a) ! this is a fortran90 style subroutine real, dimension(:) :: a a = a + 1. end subroutine incb

Si la rutina está en un módulo, las interfaces se generan automáticamente y no es necesario que se escriban explícitamente.

! THIS IS ANOTHER RIGHT WAY module inc contains subroutine incb(a) ! this is a fortran90 style subroutine real, dimension(:) :: a a = a + 1. end subroutine incb end module inc program main use inc real, dimension(5) :: x x = 0. call incb(x) print *, x end program main

Si se utilizan interfaces, la interfaz DEBE coincidir con la función real.

Entonces, continuando mi pregunta, ¿hay alguna opción en gfortran u otros compiladores para evitar la compilación si hay una llamada a un procedimiento cuya interfaz no está explícitamente definida (o definida en un módulo)?

Si no, ¿no debería ser una característica?


Para gfortran existe la opción de compilación -Wimplicit-interface :

-Procedimiento implícito
Advierta si se llama a un procedimiento que no tiene una interfaz explícita ni ha sido declarado como EXTERNO.

Esto se puede -Werror con -Werror para tratar esto como un error.

Al compilar esto (con gfortran 4.8.2)

call heffalump(1) end

Uno ve

llamar a Heffalump (1)
1
Advertencia: procedimiento llamado ''heffalump'' con una interfaz implícita en (1)

Tenga en cuenta, sin embargo, que aunque esto puede ser una prueba útil para "errores tontos" en el código moderno recientemente desarrollado, las cosas pueden ser bastante correctas y todavía no pasan esta prueba. Ver también el comentario de Vladimir F a esta respuesta.

Por supuesto, un compilador en la mayoría de las circunstancias no puede decir si el procedimiento requiere una interfaz explícita. Consulte esta respuesta para ver las opciones que le permitirán al compilador hacer un poco de trabajo adicional en ese sentido.


Sí, los compiladores tienen esto. Ifort tiene -warn interfaces , incluidas en -warn , gfortran tiene este control en -Wall .

interf.f90:6.15: call incb(x) 1 Error: Procedure ''incb'' at (1) with assumed-shape dummy argument ''a'' must have an explicit interface

Sin embargo, el compilador tendrá problemas para verificar esto si residen en diferentes archivos. Algunos lo encontrarán, otros no.

> gfortran incb.f90 interf.f90 -Wall > ifort incb.f90 interf.f90 -warn interf.f90(6): error #7978: Required interface for passing assumed shape array is missing from original source [X] call incb(x) ----------------^ compilation aborted for interf.f90 (code 1)

Como @francesalus escribe, puede forzar advertencias para interfaces implícitas -Wimplicit-interface . Sin embargo, esto hace algo diferente. Advierte de CADA procedimiento con interfaz implícita, incluso cuando es estándar para tenerlo.

Si lo conecta con -Werror , tendrá que escribir una interfaz para cada procedimiento MPI que funcione con búferes, para cada biblioteca heredada que use. Lo uso, pero mi código está estrictamente en módulos y realmente tuve que escribir las interfaces para cada procedimiento MPI que uso, que envía o recibe algún buffer. Para cada tipo de buffer, necesita una interfaz separada (al menos en Fortran 2008).

Peor aún, algunas implementaciones de MPI proporcionan interfaces explícitas para ciertos procedimientos y otras no. Una vez que hace el esfuerzo de declarar las interfaces necesarias para una versión de biblioteca MPI, otra comenzará a quejarse de que la interfaz ya está definida y difieren. (Historia real de las trincheras.)