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

Transition F77 code from Lahey Fortran to Intel IFORT

sindizzy
New Contributor I
39,753 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
Steve_Lionel
Honored Contributor III
30,819 Views

It was never OK to do this - if it "worked", it was by accident and subject to breaking without notice. I don't know what you intend here - are you trying to access characters beyond position 32? If not, then change the declaration of REC to be CHARACTER*(*), which it should be anyway.

0 Kudos
sindizzy
New Contributor I
30,793 Views

I appreciate the response. I will re-iterate my question "Is there a switch that will allow IFORT to bypass the warnings and also the run time errors?"

 

To follow up, I only gave ONE sample, and I can fix that sample. But there are tens, hundreds, maybe thousands of these mismatched interfaces. The code has been tested and confirmed to give expected results. I am just trying to change compilers before I do anything else.

 

Again "Is there a switch that will allow IFORT to bypass the warnings and also the run time errors?"

0 Kudos
andrew_4619
Honored Contributor III
30,711 Views

No, there isn't a switch and it would make no sense whatsoever to have one. It undoubtably crashes because you address beyond the length of a string. The behaviour will depend on what it is that is being corrupted so it 'might have worked' before but only through luck. You need to fix it. 25K loc is not very big it is no so big a task. 

0 Kudos
sindizzy
New Contributor I
29,843 Views

It does not crash. It has been in production for at least 20 years and validated. Thanks for the recommendation although 25k lines of code IS a big task.

0 Kudos
GVautier
New Contributor III
30,711 Views

As Lionel said, that incorrect declaration is very dangerous because it allows a subroutine to access beyond the limits of the string passed as argument and potentially affect others variables. It generates bugs often aleatory very difficult to find and fix because they depends on compiler (version, flags, optimization), linking order, changes in code and so on. Years ago, I also faces this problem in a huge legacy program and the only solution was to replace all incorrect string arguments declaration in subroutine by CHARACTER*(*) declaration. It takes time but the code is pretty much safer after that. Writing a fixing program using the compilation warnings listing to automatically proceed to the changes in source files may be a faster alternative.

Blocking the generation of warnings at compile time is not a solution because memory access violations will continue to be generated at run time and stack or memory corruption will continue to occur.

jimdempseyatthecove
Honored Contributor III
30,637 Views

Using CHARACTER*(*) declaration as @GVautier suggest .AND. running a Debug session with bounds checking enabled will help you catch indexing the character variables beyond that of the length of the character variable being passed in. IOW it will identify errors in the program that have been there for the last several decades.

 

Jim Dempsey

0 Kudos
sindizzy
New Contributor I
30,590 Views

The code has been in production for decades and thoroughly tested. Validation runs produce no errors.

The example is only one of many thousands of interface mismatches. I know how to fix the example and the others. It is not an easy task with a 25k line program. 

 

Thanks for the info though.

0 Kudos
garraleta_fortran
30,623 Views

That would be very dangerous

0 Kudos
sindizzy
New Contributor I
30,588 Views

Thanks all for the very solid information. Let me attack this problem from another angle. Let's say I am willing to dive into fixing the interfaces in the program. I turn on interface checking warn:interface and I compile. It seems like the compiler only tells me the first instance of an interface mismatch. I fix that one and then the next one pops up in the next compile. Is there a way to get ALL interface mismatches so that I can then determine how much effort will be involved?

0 Kudos
Steve_Lionel
Honored Contributor III
30,560 Views

The problem here is that you're relying on "generated interface checking" that is dependent to some degree on the order in which sources are compiled. If you're building in Visual Studio (likely given your complaint), it may miss some and doing a rebuild won't help because the generated interface modules will get deleted each time.

Here's something you can do. Create a .bat file that compiles all the source files using the options "/c /warn:interface". Open an Intel oneAPI compile command window, set default (cd) to your source folder, and run this bat file twice. The second run should include all of the mismatches.

0 Kudos
sindizzy
New Contributor I
29,837 Views

OK I only have one source file with 4 INCLUDEs. I ran the command /c /warn:interface twice and both times I got the same interface mismatches. I know there are more as I briefly started to update the subroutines and more kept popping up after each fix.

0 Kudos
andrew_4619
Honored Contributor III
29,730 Views
Have you considered using the split.for program you can find online that breaks your source into individual files one routine per file.
0 Kudos
sindizzy
New Contributor I
29,718 Views

I could do that but what would it gain me in this scenario? Do I just run /c /warn:interface on every FOR file?

0 Kudos
andrew_4619
Honored Contributor III
29,714 Views
Well having split you make a file list make a batch file and compile everything. You will get a full list of fixes needed then to scope the amount of work.
0 Kudos
sindizzy
New Contributor I
29,645 Views

I apologize but it's been a decade since I dove deep into fortran compiling. How would I go about "compiling everything"?

0 Kudos
sindizzy
New Contributor I
30,554 Views

@Steve let me give that a try and I report back.

 

Also, I have scoured the Lahey user manual and there is no switch to check interfaces. Meaning there are no checks and the runtime does not produce an error on interface mismatches. Obviously in this case it would be left to the developer.

 

The closest that I can see is -CHK but not sure that this will produce a runtime error. I will see if I can run a test or two with this switch.

 

-[N]CHK
Checking
Default: -nchk
Specify -chk to generate a fatal runtime error message when substring and array subscripts
are out of range. This includes zero- or negative-length adjustable dimension arrays. -CHK
adds to the size of a program and causes it to run more slowly.

0 Kudos
GVautier
New Contributor III
30,537 Views

In legacy fortran compilers there where no interface checking and in recent compilers, these tests are only performed at compile time. The flag you mention only check out of bound access in strings. In your case, it has no effect because the size of the string declared in the subroutine doesn't match with the actual size of the string passed as argument. It will only check that, inside the subroutine, any substring respects the declared size but not the actual size of the argument because it's not known.

garraleta_fortran
29,257 Views

Tested with VS1012_Intel®Fortran Compiler XE 13.1 and VS2022_INTEL_FORTRAN_IFX

0 Kudos
GVautier
New Contributor III
29,195 Views

Interesting result. Is it the same if the subroutine size is smaller than the actual size of the argument?

And the question is to know if this behavior is compliant with the standard and not only a compiler choice.

So if the actual string size takes over the declared size what is the utility of the warning?

0 Kudos
andrew_4619
Honored Contributor III
29,034 Views

Not interesting at all really. It is just that the memory corrupted by the code doesn't affect the output in the example, a slightly modified example however is totally foobahed as show below.  The code is not compliant and works via the luck or not  of compiler choices on where and how it stores things.

>ifx source2.f90
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2025.2.0 Build 20250605
Copyright (C) 1985-2025 Intel Corporation. All rights reserved.

Microsoft (R) Incremental Linker Version 14.30.30709.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:source2.exe
-subsystem:console
source2.obj

source2.exe
 12345
 ABCDD
 VWXYZ
 PPPPP
 PPPPP
 PPPPP
  CALL ANALYZE
  END
  SUBROUTINE ANALYZE
       CHARACTER*5 a,b,c
       A='12345'
       B='ABCDD'
       C='VWXYZ'
       WRITE(*,*)A
       WRITE(*,*)B
       WRITE(*,*)C
       CALL TBLNK(C)
       WRITE(*,*)A
       WRITE(*,*)B
       WRITE(*,*)C
END

SUBROUTINE TBLNK(REC)
        CHARACTER*80 REC
        DO I=1,80
          REC(I:I)='P'
        ENDDO
        ! do stuff        
END

 

0 Kudos
Reply