Dear Dr. Fortran,
I know this program who seems to be OK, but he is a little different from all the other programs. (Just between you and me, he is a legacy program. Don’t let that get out. It would not be politically correct.)
He started out life written for the IBM 1130 Disk Monitor System with 8k of core storage. He was written in 1130 FORTRAN. The original documentation gives direction as to which switches on the computer must be flipped to invoke certain options. But he is still alive and works well. We still add things to him. He lives on PCs now.
We really don’t view him as belonging to us. His original programmers have retired and some have died. So in that respect he is doing better than his creators. We are like park rangers taking care of some national treasure that is to be passed on to our successors.
But lets give this a go. I need some help understanding what really goes on in this guys head. There are many cases of the following coding:
subroutine xyz(n,array) integer n real array(1)
My questions are:
- Why does this work? It seems an out of bounds exception should be generated for array since its size is only 1.
- In the main program the arrays are explicit shape. What type is array in subroutine xyz?
- Is array(1) standard FORTRAN, or is this something that most compilers just allow?
De Leuw, Cather and Co.
Dear Mr. Magliola,
When this charming program was written, in the days of keypunches and storage drums, FORTRAN IV (FORTRAN-66) was the current standard. While FORTRAN IV did have the “adjustable array” feature, (which could have been used in the above example by using “array(n)” instead of “array(1)”), it did not have the “assumed-size array” feature (where the rightmost upper bound is specified as “*”) that was to be introduced in FORTRAN 77. Therefore, programmers who wanted to write subroutines which would accept an array of unknown total size would use a last dimension of 1. This worked because the last upper bound is not needed to calculate the position of an element in a Fortran array, and compilers of the time didn’t have array bounds checking (or if they did it could be disabled).
Now fast-forward to 1978 when the FORTRAN 77 standard was adopted. It included a new “assumed-size” array feature (which had already shown up as an extension in many vendors’ compilers). So now there was a standard-conforming way to say “I don’t know what the upper bound is”, yet there were still thousands of existing programs that used the old (1) convention and more compilers supported bounds-checking, even at compile-time (VAX FORTRAN did this, for example.) These old programs would suddenly start getting errors, which was not desirable – the Fortran tradition is provide as much upward compatibility as possible. What to do?
The solution was to have compilers treat a last upper bound of 1 as a special case that was equivalent to *, disabling bounds checking (which answers your first question). The array in the above example has a single dimension with
lower bound 1 and an implicit upper bound of the total number of elements in the array that was passed, though most compilers don’t pass that information and just treat the upper bound as infinite (questions two and three.) It is valid to have a multi-dimension assumed-size array, but only the rightmost (last) dimension can have an upper bound of * (or 1 treated as *). If you have a multi-dimension array with upper bounds other than the last of 1, then 1 is what you get.
I hope you have enjoyed this trip back into the history of the Fortran language.
(From Intel Developer Zone, copied with permission)