2010-05-21 13 views
28

buena práctica dicta que los argumentos de subrutina en Fortran deben tener cada uno un intento especificado (es decir, intent(in), intent(out) o intent(inout) como se describe this question):intención Fortran (inout) versus omitiendo intención

subroutine bar (a, b) 
    real, intent(in) :: a 
    real, intent(inout) :: b 
    b = b + a 
    ... 

Sin embargo, no especificando una intención Fortran es válida:

subroutine bar (a, b) 
    real, intent(in) :: a 
    real :: b 
    b = b + a 
    ... 

¿hay diferencias reales más allá del tiempo de compilación para un argumento especificado como un argumento intent(inout) y sin especificado en ¿tienda? ¿Hay algo de lo que deba preocuparme si estoy adaptando los intentos al código antiguo, libre de intento?

Respuesta

20

Según The Fortran 2003 Handbook por Adams, et al., Existe una diferencia entre un argumento de intención (inout) y un argumento sin intención especificada. El argumento real (es decir, en la persona que llama) en el caso de intención (inout) siempre debe ser definible. Si no se especifica el propósito, el argumento debe definirse como si la ejecución de la subrutina intenta definir el argumento ficticio. definible significa establecer el valor: dummy_arg = 2.0. Claramente, el argumento real debería ser una variable si esto se hace. Para la intención (inout), el argumento real debe poder definirse independientemente de si la subrutina hace esto o no. Sin ninguna intención especificada, depende de lo que ocurra en esa invocación particular de la subrutina: si la subrutina no define la variable, está bien; si lo hace, entonces hay un problema - casos como escribir en un argumento real que es una constante obviamente causará problemas.

Esto no significa que el compilador diagnosticará todos estos casos; lo que el estándar requiere que el compilador diagnostique es un problema diferente. Sería casi imposible detectar todos los errores del requisito de caso de intención no especificada en tiempo de compilación, ya que las violaciones dependen del flujo de tiempo de ejecución del código. Es mucho más fácil para el compilador diagnosticar el caso de intento (inout) y advertirle de problemas con el código.

5

Su pregunta me lleva a preguntarme (hay mucho por hacer en este momento) si puede encontrar una diferencia en el comportamiento si su código pasa un PARÁMETRO como argumento real en el que su subprograma intenta escribir. Sin una declaración INTENT el compilador podría dejar esto ir, lo que lleva a un comportamiento extraño. Con la declaración, esperaría un error en tiempo de compilación.

Usted y yo podríamos pensar que no hay diferencia entre las declaraciones INOUT y no INTENT, pero no olvide que existen muchos programas Fortran antiguos y que la compatibilidad con versiones de idiomas más antiguos es una característica importante de los nuevos estándares. Si fue correcto (pero dudoso) FORTRAN77, entonces mucha gente espera que su código permanezca correcto (aún dudoso) con un compilador Fortran 90+.

Una lectura rápida de la norma 2003 indica que existe una diferencia entre INOUT y no INTENT, pero se requiere una lectura más detallada. Si lo hace, háganos saber sus conclusiones; si tengo tiempo después, lo probaré yo mismo y se lo haré saber.

+3

He construido cuatro casos de prueba tratando de modificar un parámetro en una subrutina. Dos pruebas con subrutinas externas, es decir, en un archivo por sí mismas, con y sin intención (inout). El compilador no se queja de ninguno de esos. Esto no es una sorpresa (sin interfaz) y el resultado resultante es seg. He pegado la subrutina en un módulo para las dos últimas pruebas y veo la segfault para el caso sin intención y un error del compilador ("El argumento real en (1) debe definirse ya que el argumento ficticio 'b' es INTENT = OUT/INOUT ") con la interfaz. Esto es con gfortran 4.4.4-2 desde un sistema Debian. –

+0

Excelente, ambos aprendimos algo. –

+1

En estos días, los parámetros se colocan en una parte de memoria solo de lectura, pero esto no siempre ha sido cierto. El famoso ejemplo en compiladores muy antiguos fue la redefinición de las constantes numéricas http://coding.derkeiler.com/Archive/Fortran/comp.lang.fortran/2005-01/0485.html –

3

Para comprender el rol de la intención de entrada/salida, necesita saber que, internamente, Fortran efectivamente pasa variables por referencia. Esto no es siempre lo mismo que pasar realmente por referencia.

Si pasa una subsección interna de una matriz 2-D a una subrutina, es decir: data(i1:i2, j1:j2), Fortran copia esos datos en una sección contigua de la memoria y pasa la nueva dirección a la rutina. Al regresar, los datos se vuelven a copiar en su ubicación original.

Al especificar INTENT, el compilador puede saber omitir una de las operaciones de copia.

No solo actúa como una protección a prueba de fallas para modificar los datos que desea permanecer sin cambios, sino que también puede acelerar su código cuando se trata de grandes conjuntos de datos.

Cuestiones relacionadas