Detectar matrices no inicializadas
En el siguiente programa, las dos rutinasset_int_array
yset_real_array
definir algunos valores para matrices ficticias, pero suponga que la inicialización dea(:)
yr(:)
(Las líneas 1 y 2) faltan inadvertidamente (es decir, ambas líneas deben estar descomentadas en el programa correcto). Mi pregunta es cómo detectar estos errores automáticamente con algunas opciones del compilador.
module mymod
implicit none
contains
subroutine set_int_array ( a )
integer, intent(out) :: a(:)
integer k
! a(:) = 10 !! (1)
do k = 1, size(a)
a(k) = a(k) + k
enddo
end subroutine
subroutine set_real_array ( r )
real, intent(out) :: r(:)
integer k
! r(:) = 10.0 !! (2)
do k = 1, size(r)
r(k) = r(k) + k
enddo
end subroutine
end module
program main
use mymod
implicit none
integer :: a(5)
real :: r(5)
call set_int_array ( a ) ; print *, a(:)
call set_real_array ( r ) ; print *, r(:)
end program
Para hacerlo, primero probé la siguiente opción para gfortran4.8 (en Linux x86_64):
gfortran -Wall -fcheck=all test.f90
pero esto no pudo detectar la inicialización faltante y dio el resultado incorrecto
1 2 268435459 32730 207
1.0000000 2.0000000 3.0000000 4.0000000 5.0000000
Así que probé la siguiente opción para inicializarr(:)
conNaN
:
gfortran -finit-real=snan -ffpe-trap=invalid test.f90
que captó con éxito el error deset_real_array
, pero no paraset_int_array
-1098847551 59 -1034862589 32608 7941
Program received signal 8 (SIGFPE): Floating-point exception.
Backtrace for this error:
#0 0x00000039becac5f4 in wait () from /lib64/libc.so.6
#1 0x00000039c501400d in ?? () from /usr/lib64/libgfortran.so.3
#2 0x00000039c501582e in ?? () from /usr/lib64/libgfortran.so.3
#3 0x00000039c50146ca in ?? () from /usr/lib64/libgfortran.so.3
#4 <signal handler called>
#5 0x0000000000400bd3 in __mymod_MOD_set_real_array ()
#6 0x0000000000400e69 in MAIN__ ()
#7 0x0000000000400f52 in main ()
Como tal, también probé ifort14.0 con las siguientes opciones
ifort -check all test.f90
ifort -check uninit test.f90
pero ambos no pudieron detectar los errores. De hecho, la página del manual paracheck uninit
la opción dice
Solo localescalar Se verifican las variables de tipo intrínseco INTEGER, REAL, COMPLEX y LOGICAL sin el atributo SAVE.
entonces puede ser natural que no se detecten los errores. Entonces mi pregunta es: ¿hay algún método para detectar los errores dea(:)
yr(:)
¿automáticamente?
[Editar] Mi motivación para esta pregunta proviene deuna publicación reciente en SO, donde el OP tuvo dificultades para encontrar un error. Resultó que el problema proviene del uso de una matriz no inicializada encurve_derivs_alg1()
en elevaluate
módulo, pero fue muy difícil para mí también encontrar la ubicación precisa del error (aunque puede parecer trivial una vez que se encuentra). los-finit-real-snan -ffpe-trap=invalid
La opción funciona en este caso, pero debería ser mucho más difícil si las matrices enteras fueran el problema ... Entonces me preguntaba si hay algunas opciones convenientes o formas de rastrear la primera ubicación del uso de matrices no inicializadas.