Many old codes do not specify intent for procedure arguments. When I write interfaces to these, my habit is to provide intent when I can infer it. For example, LAPACK clearly documents the intent of each argument. I was surprised to learn recently that my habit may be wrong.
Consider the following subroutine and program defined in separate files
subroutine sub(i, o, io)
integer :: i, o, io
o = i+1
io = 2*io
end subroutine
program ex
implicit none
interface
subroutine sub(i, o, io)
integer, intent(in) :: i
integer, intent(out) :: o
integer, intent(in out) :: io
end subroutine
end interface
integer :: o, io
io = 2
call sub(9, o, io)
print *, o, io ! expect: 10 4
end program
I found that gfortran 13.2.0 (-std=f2018
) as well as ifort 2021.11.0 and ifx 2024.0.0 (-standard-semantics
) all happily compile both of these and produce the expected output when run.
However, if I place the subroutine and program in the same file, gfortran rejects it:
Error: Interface mismatch in global procedure 'sub' at (1): INTENT mismatch in argument 'i'
Perhaps it is worth noting that if I do not ask for standards conformance or choose -std=legacy
, gfortran simply emits a warning rather than an error.
This is my first time encountering such an mismatch issue. I suppose in the past, I had never seen this because the libraries I was linking to (e.g., LAPACK) were pre-compiled binaries, so the compiler had to trust that my interface was correct. However, it seems that gfortran can sometimes use its compile-time knowledge of sub
here to catch the mismatch. On the other hand, ifort and ifx do not complain in either case.
This has some unfortunate implications for using old code that does not specify intents. For example, it is incorrect to call such code from within pure procedures, since pure
requires that all intents are specified. Likewise, elemental procedures calling intentless procedures have to be declared impure elemental
.
I have two questions:
-
Can anyone confirm that indeed, it is illegal to add intent where none was originally specified?
-
If it is illegal, what workarounds are there to correctly use legacy code in
pure
orelemental
contexts?