In a medium sized program (www.netlib.org/odepack) that I am attempting to modernize, I have reached what appears to be a stumbling block.
The program is over 31,000 lines of code, about 1.3 Mbytes in all, including nine test drivers and three files with the ODE solver routines, all Fortran 77 with lots of common blocks, etc. With the help of FTN95 I found a few instances of uninitialized variables, and fixed those issues.
With one of the test problems, I suspect that there are arrays being accessed out of bounds, but I am unable to use FTN95 8.91 with /check to analyse the problem, since the program stops early with a spurious error.
The short program that I give below contains the gist of the issue. A procedure (in this case, a subroutine) is passed as an argument to a subroutine, which passes it along to one or more other subroutines. No interfaces are provided and implicit typing is relied upon, since adding declarations and interfaces to the Odepack program would require considerable effort.
program impasse
external fsub ! fsub is intended to be a subroutine
real x,y
y = 25.0
x = 4.0 !trial value of root
call solve(x,y,fsub)
print *,'Root is ',x
end program
subroutine solve(x,y,fsub) ! this subroutine is just an intermediary
real x,y ! the arg FSUB is passed along
external fsub ! is fsub a function or a subroutine?
call find_root(x,y,fsub)
print *,'Solve found root as ',x
return
end subroutine solve
subroutine find_root(x,y,fsub)
real x,y
real x1,x2,y1,y2
integer iter
iter = 0
do
x1 = x
call fsub(x1,y1)
x2 = x*1.01
call fsub(x2,y2)
der = (y2-y1)/(x2-x1)
x = x1 - (y1-y)/der
print *,x,y1,y2
if(abs(y1-y) < 1e-4)exit
iter = iter+1
end do
return
end subroutine
subroutine fsub(x,y)
real x,y
y = x*x
return
end
This program runs without error when built with these compilers: Compaq, Gfortran, Lahey, Intel and NAG. The small test program is, I believe, error-free.
When built and run with FTN95 8.91 with /check, the program stops early:
Runtime error from program:s:\lang\ftn95\extbug.exe
Run-time Error
Attempt to call a routine with argument number three as a procedure when a real(kind=1) was required
SOLVE - in file extbug.f90 at line 10 [+005c]
main - in file extbug.f90 at line 7 [+006c]