Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29270 Discussions

Transition F77 code from Lahey Fortran to Intel IFORT

sindizzy
New Contributor I
39,743 Views

I have inherited a fairly sizable program written in F77 and compiled with Lahey Fortran 90 Compiler Release 4.50i. I am looking to transition to IFORT (yes I know its deprecated but still require x86 targets).

 

The code is 25k+ lines of code and has been in production for at least several decades. I have done very minimal changes and was able to compile it successfully with IFORT. Now, the issue is with mismatches in interfaces. A sample is transcribed below in its simplest form.

 

From what I have gathered this was ok to do in the old days and some compilers even allowed it without too much trouble. (Doesn't mean it was right). If I omit the IFORT switch warn:interfaces it will bypass the compile warning BUT it will still throw an error when running the program.

 

There are many, many other instances of these interface mismatches. Is there a switch that will allow IFORT to bypass the warnings and also the run time errors?

 

SUBROUTINE ANALYZE
       CHARACTER*32 a,b,c
       !read a, b, and c
       CALL TBLNK(a)
END

SUBROUTINE TBLNK(REC)
        CHARACTER*80 REC
        ! do stuff        
END

0 Kudos
50 Replies
garraleta_fortran
5,452 Views

This is the explanation

The variables A, B, C are ordered in REVERSE POSITION

0 Kudos
Steve_Lionel
Honored Contributor III
5,453 Views

"If a present scalar dummy argument is of type character with default kind or C character kind, the length len of the dummy argument shall be less than or equal to the length of the actual argument. The dummy argument becomes associated with the leftmost len characters of the actual argument." 15.5.2.5p4 (emphasis mine)

0 Kudos
GVautier
New Contributor III
5,444 Views

OK

It confirms that such buggy programs work only by chance.

AndrewC2
Beginner
4,902 Views

What exactly was the runtime error your program encountered when it was recompiled with IFORT. It may be unrelated to this particular issue. Can you run under the debugger to verify the call stack.

Despite how much the compiler complains I don’t believe the interface mismatch you show should cause an issue as long as the “called” routine does not access the string beyond the 32 index.

I have recompiled some ancient F77  code bases with lots of similar interface mismatches.

0 Kudos
sindizzy
New Contributor I
4,421 Views

The warning was there was an interface mismatch. The runtime error was the same...interface mismatch.

0 Kudos
GVautier
New Contributor III
4,847 Views

It is said that the program works correctly. Apparently!
Yes, this code may work if there is no access (read or write) beyond the actual length of the argument string but it's very odd to declare a 80 characters length string in a subroutine and have the discipline inside it to not access beyond another length (may be variable). It's easier and safer to declare the correct string length if constant or use a deferred length (character*(*)) if not.

 

0 Kudos
AndrewC2
Beginner
4,770 Views

I take the OP's statement as fact that the program is well tested and runs fine when compiled with the old Lahey compiler.  

He has stated that several times!

However, the OP does state that after compiled with IFORT "it will still throw an error when running the program."

My point is that he might be "chasing ghosts" as the runtime error is quite likely to be unrelated to the CHARACTER  parameter issue. There are many subtleties when dealing with old F77 code when standards were "fluid" and compiler vendors had some specific extensions. 

Maybe the OP will weigh in. 

0 Kudos
andrew_4619
Honored Contributor III
4,761 Views

"quite likely to be unrelated...." i would say is only possibly unrelated, as I demonstrated upthread this can quite easily work 'fine' in one instance and fail in another with the SAME compiler.  It is a bug and in my long and bitter experience it is best to fix non conformances like this as you can make entirely unrelated code changes and all of a sudden the code is broken because the memory you are corrupting has randomly gained importance. So many hours wasted....  I only accept standard conforming code with  no extensions even if it makes coding more verbose at times. 

0 Kudos
AndrewC2
Beginner
4,720 Views

What you showed "upthread" was that if you pass a string of length 5 to a routine that declares the parameter  of length 80 and that subroutine then writes into locations beyond index 5 you will crash the code. No argument there. It will be sort of random what happens of course.

But the OP has stated that the existing and functioning code does not write outside the bounds of the passed in string. 

Also no argument that this is not great code, to say the least, but we often inherit legacy code and have to deal with it "as-is". 
"if it ain't broke, don't fix it" has a lot of appeal when the code in question is probably in "maintenance" mode.

 

0 Kudos
andrew_4619
Honored Contributor III
4,480 Views

No we did not crash the code we demonstrated that you could get correct results or incorrect results. Unless the Intel compiler makes that same decisions on storage location as Lahey there is no guarantee that the code will work.  And it is also clear this code is broken.

sindizzy
New Contributor I
4,412 Views

Appreciate the feedback. I am still trying to find a way to get a list of all interface mismatches so that I can then determine how much effort will be involved. I have not been able to do that with the suggestions. Maybe it is one of those things where you just have to whittle at it little by little.

0 Kudos
sindizzy
New Contributor I
4,422 Views

My initial tests showed that a warning would be shown "interface mismatch". I bypass that check by removing the switch and I run the program. The runtime error is also "interface mismatch.

0 Kudos
sindizzy
New Contributor I
4,422 Views

The warning is interface mismatch. if I remove that switch and run the program the run time error is the same... interface mismatch. Let me see if I can take a snapshot.

0 Kudos
sindizzy
New Contributor I
4,422 Views

Its not "apparently" it has been in production for at least 2 decades and results validated against known cases. The compiler used did not flag interface mismatches.

0 Kudos
sindizzy
New Contributor I
4,368 Views

Thanks for all the help and suggestions. Here is a run of the program after removing the interface mismatch warnings. When I run it, I get a typical runtime error like below. The subroutine is coded to receive an 80 char REC. In calling the subroutine a 70 char var is provided.

 

YES I know this is not proper coding. YES I know it could cause unwanted and random side effects. The program has worked in production for several decades and rigorously validated. YES I know that doesn't make it right. YES I know it works by chance. Thank you for setting me on the right path. I appreciate it. I really do. These are not words of sarcasm.

 

I just recently inherited this project and my focus has now shifted to fixing the code so I can port it to IFORT. The program is ~25k lines and looking for a way to enumerate the interface mismatches rather than work on one by one. I can then determine how big the job will be. My question...is there a way to determine ALL interface mismatches in one shot?

 

sindizzy_0-1753554680221.png

 

0 Kudos
GVautier
New Contributor III
4,356 Views

Why not replace all character arguments declarations in functions and subroutines by character*(*) declarations?

Unless if accesses beyond string bounds were intentional, I thinks it's safe.

0 Kudos
andrew_4619
Honored Contributor III
4,323 Views
How many source files do you have? I can give you the method to get an error list.
0 Kudos
sindizzy
New Contributor I
4,315 Views

Only one source file with 2 includes. The methodology suggested before was to split them into individual subroutines and then compile each one. That will just give me errors where the compiler can't find a subroutine. I don't think it will give me interface mismatches.

0 Kudos
andrew_4619
Honored Contributor III
4,251 Views

I modified the Burkhardt f90split.f90 (works on f77 also). It is attached.

 

1] create folder  and drop f90split.f90 in it

2] open an intel command prompt

3] in the cmd prompt cd to your folder

4] ifx f90split.f90 to create f90split.exe

5] drop your source and includes in to the folder

7] run the splitter:

f90split yoursource.for

 

8] I modified the Burkhardt f90split.f90 , it will create files_list.bat and  a whole load of fortran files one for each subroutine or function.

9] run the bat file and it will compile each file with gen interfaces

10] run the bat file a second time and it will throw up all the interface errors because all the genmod files will exist the second time.

 

 

 

0 Kudos
sindizzy
New Contributor I
3,995 Views

Let me try this and I will report back tomorrow. Thank you again.

0 Kudos
sindizzy
New Contributor I
4,314 Views

Again, this is one, just one, of many subroutines in the code. I can fix this one easy. Compile then the next one pops up, Fix that one. Compile. Next. 

0 Kudos
Reply