C++Guns – RoboBlog

11.04.2015

Local variable will not retain values between function invocations (Bug of the day 2)

Filed under: Allgemein — Tags: — Thomas @ 07:04

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

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress