- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That would be very dangerous
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I could do that but what would it gain me in this scenario? Do I just run /c /warn:interface on every FOR file?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I apologize but it's been a decade since I dove deep into fortran compiling. How would I go about "compiling everything"?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page