I’m trying to convert some old F77/f90 subroutines to modern Fortran.
I have this subroutine that in the declaration of inputs has
How can this case be handled?
Apart for adding an intent(inout) statement, I don’t know how to declare the lower and upper bounds of the input array.
When I call this subroutine in my program valgrind detect a read past the array limits, but the compiler gfortran detects nothing and the program crashes at runtime.
I assume it looks like this:
subroutine f(imin, imax, jmin, jmax, kmin, kmax, bf)
You can either leave it, or you can do:
subroutine f(imin, jmin, kmin, bf)
! real bf(imin:,jmin:,kmin:,3) ! Not sure right now if this is allowed
real bf(imin:,jmin:,kmin:,:) ! This should work
This would keep the lower bounds and the upper bound would be runtime. Finally, you can also do:
But then the lower bound will be 1.
There is some contrarian thinking reemerging recently with
explicit-shape arrays in Fortran which is what you have at the moment. Unfortunately though there is little support for defensive/safe programming against it in the language.
Until that might appear (in a distant future), my personal suggestion will be to follow the route set forth with “modern” Fortran starting with the Fortran 90 standard revision.
Which is to use the combination of explicit interfaces readily achieved via module procedures and also assumed-shape arrays.
Also, to think along the lines of library development as a collection of codes toward a particular “physics” (or math, economics, etc.) problem in what might be a multi"physics" solution/application i.e., many effects get considered together. Then in one or more such collections, it is possible the codes like to work with particular lower bounds that are different from unity. In that case, look at alternate options to achieve such lower bounds such as
- named constants (parameter attribute) at the
- module entities that have setter methods (and getter if need be),
- parameterized derived types where the length/kind type parameter facilitates lower bound handling via a OO “class” type of approach.
Followed by the use of some run-time assertion approach (may be a simple
assert subroutine) to ensure the shapes of arrays in the procedures are as expected: see this, it may already be on the anvil with Fortran stdlib
Aside from the higher-level issues already being discussed, I am wondering why gfortran did not trap the error. If not already doing so, are you including compiler options similar to the following?
-Wall -Wextra -Wimplicit-interface -fcheck=bounds -fcheck=array-temps -fbacktrace
@certik It turned out, as you said, that leaving
was acceptable for the compiler and probably the best solution for future maintenance.
@FortranFan Thank you for your suggestions
@urbanjost I was already using all of them, the error was caught after adding
intent(...) to the arguments.