Equivalence behavior across Windows and Linux for legacy code from VMS

Equivalence behavior across Windows and Linux for legacy code from VMS

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


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,














5 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

If EQUIVALENCE has been used only to reduce the memory required by the program, removing such EQUIVALENCEs should have no effect on the program results. Have you investigated whether this conjecture is true?

How big is the program and how long does it take to run, typically?

Do you have DATA statements to initialize your COMMON?   Please try compiling your application with standards checking turned on and see if you get any messages about multiply-defined variables within the COMMON.  If a common variable is being declared twice, it may be being done in a different order between Windows and Linux.

There is nothing in the Intel Fortran compiler that is OS-specific relating to EQUIVALENCE.  That is, there is no different handling for Windows vs Linux.

If the original code is older than VAX Fortran days, it may have been deliberately writing outside of bounds, "knowing" that one short array was equivalence to a bigger array. 

Finally, if you can post the exact commands used for both Linux and Windows compilation there might be a clue there too.


Out-of-bounds access might be expected to produce different results on Windows and linux (or even with the same OS on different installations).

Unexpected access to the zero element of an array might indicate an undefined subscript variable.

Thank you everyone for your insight. I will take a new look through the lens of your ideas.

Leave a Comment

Please sign in to add a comment. Not a member? Join today