Erkennen von nicht initialisierten Arrays
Im folgenden Programm werden die beiden Routinenset_int_array
undset_real_array
definiere einige Werte für Dummy-Arrays, aber nehme an, dass die Initialisierung vona(:)
undr(:)
(Zeilen 1 und 2) fehlt versehentlich (d. H. Beide Zeilen sollten im richtigen Programm nicht kommentiert sein). Meine Frage ist, wie diese Fehler mit einigen Compiler-Optionen automatisch erkannt werden können.
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
Dazu habe ich zuerst die folgende Option für gfortran4.8 (unter Linux x86_64) ausprobiert:
gfortran -Wall -fcheck=all test.f90
dies konnte jedoch die fehlende Initialisierung nicht erkennen und ergab das falsche Ergebnis
1 2 268435459 32730 207
1.0000000 2.0000000 3.0000000 4.0000000 5.0000000
So habe ich versucht die folgende Option zu initialisierenr(:)
mitNaN
:
gfortran -finit-real=snan -ffpe-trap=invalid test.f90
die den Fehler für @ erfolgreich abgefangen hset_real_array
, aber nicht fürset_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 ()
Als solches habe ich auch ifort14.0 mit folgenden Optionen ausprobiert
ifort -check all test.f90
ifort -check uninit test.f90
, aber beide konnten die Fehler nicht erkennen. In der Tat ist die Manpage fürcheck uninit
Option sagt
Nur lokal scalar Variablen des intrinsischen Typs INTEGER, REAL, COMPLEX und LOGICAL ohne das SAVE-Attribut werden überprüft.
dann kann es natürlich sein, dass die Fehler nicht erkannt werden. Meine Frage lautet also: Gibt es eine Methode, um die beiden Fehler für @ abzufangea(:)
undr(:)
automatisch?
[Bearbeiten] Meine Motivation für diese Frage kommt vona letzter Beitrag auf SO, wo es dem OP schwer fiel, einen Bug zu finden. Es stellte sich heraus, dass das Problem von der Verwendung eines nicht initialisierten Arrays in @ herrührcurve_derivs_alg1()
in demevaluate
module, aber es war sehr schwierig für mich, auch den genauen Ort des Fehlers zu finden (obwohl es trivial erscheinen kann, wenn es gefunden wird!). Das-finit-real-snan -ffpe-trap=invalid
ie @ -Option funktioniert in diesem Fall, aber es sollte viel schwieriger werden, wenn ganzzahlige Arrays das Problem sind. Ich habe mich also gefragt, ob es einige praktische Optionen oder Möglichkeiten gibt, den ersten Ort für die Verwendung nicht initialisierter Arrays zu ermitteln.