Lokale Variablen behalten ihren Wert NICHT zwischen Funktionsaufrufe!
Es gibt in diesem Beispiel keinen Compilerfehler und auch keinen von Fortran erkannten Laufzeitfehler.
Es gibt Compiler Warnings die diesen Fehler zeigen, aber dazu bedarf es mehr Code. Ich habe dieses Beispiel möglichst klein und übersichtlich gehalten.
Ausgabe ohne Optimierung und ohne Fehler
kater@ktux:~$ gfortran -Wall -Wextra -fcheck=all bugoftheday_openreadclose.f95 kater@ktux:~$ ./a.out first round DEBUG address of fhdl BFC4D8FC open. set fhdl to 100 read all file second round DEBUG address of fhdl BFC4D8FC open. set fhdl to 100 DEBUG address of test BFC4D90C set test variabel to 1000 read all file
Man beachte die unterschiedlichen Adressen der lokalen Variablen. Daher wird der Fehler nicht getriggert.
Ausgabe mit Optimierung und mit Fehler
kater@ktux:~$ gfortran -Wall -Wextra -fcheck=all bugoftheday_openreadclose.f95 -O1 kater@ktux:~$ ./a.out first round DEBUG address of fhdl BFA7DE38 open. set fhdl to 100 read all file second round DEBUG address of fhdl BFA7DE38 open. set fhdl to 100 DEBUG address of test BFA7DE38 set test variabel to 1000 read ERROR expect fhdl to be 100 but is 1000
Diesmal sind die Adressen der lokalen Variablen gleich! Die Variable fhdl wird ungeplant ueberschrieben!!
Welche Adresse die lokalen Variablen bekommen und ob so der Fehler auftritt oder nicht, ist zufällig und nicht beeinflussbar!!!
! Local variable will not retain values between function invocations
! compile: gfortran -Wall -Wextra -fcheck=all bugoftheday_openreadclose.f95
! turn on any optimization to trigger the error
subroutine openread(action)
use testmodule
implicit none
character(len=*), intent(in) :: action
integer :: fhdl
if(action == 'open') then
fhdl = 100
write(*,'(A,Z16)') "DEBUG address of fhdl ", loc(fhdl)
write(*,*) "open. set fhdl to", fhdl
else if(action == 'read') then
write(*,*) "read"
if(fhdl /= 100) then
write(*,*) "ERROR expect fhdl to be", 100, "but is", fhdl
else
write(*,*) "all file"
endif
else if(action == 'close') then
write(*,*) "close fhdl", fhdl
endif
end subroutine
subroutine overwriteLocalValue()
implicit none
integer :: test
test = 1000
write(*,'(A,Z16)') "DEBUG address of test ", loc(test)
write(*,*) "set test variabel to", test
end subroutine
program bugoftheday
use testmodule
implicit none
write(*,*) "first round"
call openread("open")
call openread("read")
write(*,*)
write(*,*) "second round"
call openread("open")
call overwriteLocalValue
call openread("read")
end program