j3-fortran / fortran_proposals

Proposals for the Fortran Standard Committee
178 stars 15 forks source link

Make passing an intent(in) argument to a procedure with unspecified intent obsolescent #228

Open Beliavsky opened 3 years ago

Beliavsky commented 3 years ago

Compilers do not warn you if you pass an intent(in) argument as an argument with unspecified intent to another procedure. This allows you to inadvertently write code where an intent(in) argument changes its value within a procedure, for example

module m
implicit none
contains
subroutine foo(i)
integer, intent(in) :: i
call increment(i)
end subroutine foo

subroutine increment(i)
integer :: i
! integer, intent(in out) :: i ! will not compile if this line uncommented
i = i+1
end subroutine increment
end module m

program main
use m, only: foo
implicit none
integer :: i
i = 3
call foo(i)
print*,i ! gives output 4
end program main 

I suggest that passing an intent(in) variable to a procedure as an argument that is not intent(in) be made obsolescent, so that compilers will warn about this. The user could add intents where needed, make copies of intent(in) arguments passed to procedures without intents, or ignore or turn off the warning. There is much modern Fortran code with intents that calls Fortran 77 code without intents, so making it illegal will not be feasible for a long time.

For pure and elemental procedures, the language is strict. A pure procedure can only call procedures that are declared pure or elemental. It is not enough that those procedures satisfy the properties of pure procedures. I am suggesting that the requirements for intent(in) be similarly strengthened. This idea has been discussed on Fortran Discourse.

klausler commented 3 years ago

There is a distinction to be made between procedures with explicit interfaces and no INTENT vs. procedures with implicit interfaces. The "Fortran 77 code without intents" that you mention are procedures with implicit interfaces, not procedures with explicit interfaces and no INTENT.

certik commented 3 years ago

As @klausler said, I always call F77 code by writing an explicit interface and specify intent. Then I think there is no problem and even old code will work with the above proposed warning on.

jacobwilliams commented 3 years ago

If it was up to me Fortran would:

certik commented 3 years ago

Thanks @jacobwilliams. Added both into https://gitlab.com/lfortran/lfortran/-/issues/450. I think this can be fixed by a compiler simply giving an error. I bet a lot of people would enable such a mode even by default. (Obviously one could turn it off.)