- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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 copiado
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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?"
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
That would be very dangerous
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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?
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
I could do that but what would it gain me in this scenario? Do I just run /c /warn:interface on every FOR file?
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
I apologize but it's been a decade since I dove deep into fortran compiling. How would I go about "compiling everything"?
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
@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.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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.
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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?
- Marcar como novo
- Marcador
- Subscrever
- Silenciar
- Subscrever fonte RSS
- Destacar
- Imprimir
- Denunciar conteúdo inapropriado
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

- Subscrever fonte RSS
- Marcar tópico como novo
- Marcar tópico como lido
- Flutuar este Tópico para o utilizador atual
- Marcador
- Subscrever
- Página amigável para impressora