I have inherited some FORTRAN from VMS. It looks like it moved from VAx to Alpha/AXP and now headed to Window 7 and later and to Linux Redhat 5x and later. Building on VMS/Alpha with check/all reveals the code will not run! Therefore this port is already tainted. There is a "bless" input and output file set and is being used as the exit criteria for the port.
I initially took the software to Windows and kept turning off default options in the Intel Fortran V11x compiler until it provided a nearly identical output file. I then turned on important options like check/all and got the array sizes increased to fix bounds issues. I next fixed the interface issues after turning that switch back on. The output is nearly identical except for some odd formatting issues in the output file, but the numbers all appear to vary in the 4th or low decimal place. Of course how do you know if this correct since this software has been modified over the years without proper maintenance.
I am using the following flags (writing this from memory):
-vms -debug full -noalign -gen-interfaces -check-interfaces -check all -save -zero -fpe0 -i4 -r8
I moved the code to Linux and built it and it dies quickly. I use the same compiler switches as above. The following is happening:
1. To save space back on the VAX this software is equivalenced all over the place and many times multiple names for the local storage for the same common block (e.g. /A/ A can be locally equivalenced to BOB, FRED, CAT, etc... in many different subroutines) /A/ is an array of Real*8 and the other locally defined storage are Integer*4. A function, IIN(KIN) = 2*KIN - 1 is used to access special integer values from the common blocks.
2. Someone even passed both common block variables as subroutine arguments as well as the equivalenced variables.
On Windows: COMMON /TABLE/ TABLE(50000) (Real*8) is equivalenced to ITABLE(100000) (Integer*4) local storage
EQUIVALENCE (TABLE, ITABLE)
val = itable(IIN(1)) => val equals 201 in itable(1)
On Linux: Same code just rebuilt
val = itable(INN(1)) => val equals 0 in itable(1)
If you examine itable(1) and itable(2) on Windows and on Linux they are opposite of one another in value. This applies to the entire itable array.
It gets uglier when looking at passing these as arguments under the following condition:
I redefined itable(100000) to be itable(0:100000) and this fixed many references problems in subroutines addressing the locally declared storage. however passing this type of array required doing this in the subroutine it was passed to: ltab(0:*), but fails to work when passed to the next call down below it. This is getting into the weeds. Getting the COMMON data out of the calling arguments is a huge job
I want to know how the above EQUIVALENCE statement above can behave differently from one OS to another. I have played with all the -align options and even the -pad. I don't mind having to clean up the subroutine calls and do the zero-based array for the local storage if I can understand why this is needed on Linux. I use to write code like this in the 70's and 80's and it has a cyclomatic complexity of 1,000,000,000, but I don't do this anymore. 50% of the statements in the code is GOTO which go everywhere.
Thanks in advance,