In a subroutine or function an input variable can be defined with intent(in) and the compiler assures that within the subroutine the variable can not be altered. As soon as
With sufficient compiler options gfortran generates a warning for your example, that an implicit interface is used.
If you make the interface explicit by placing the subroutines into a module, and use intents for all arguments, gfortran will catch the problem:
module mysubs
contains
subroutine test(i)
integer, intent(in) :: i
call doSomethingNasty(i)
end subroutine
subroutine doSomethingNasty(i)
integer, intent (inout) :: i
i = 42 ! set the full truth ;-)
end subroutine
end module mysubs
program Test_intent_in
use mysubs
integer i
i = 21 ! half the truth
call test(i)
write (*,*) "21 expected, but is 42: ", i
end program Test_intent_in
gfortran gives error message:
call doSomethingNasty(i)
1
Error: Procedure argument at (1) is INTENT(IN) while interface specifies INTENT(INOUT)
When pass the argument "(i)" you are passing an expression rather than a variable. The expression is not definable and thus should not be used as an actual argument for an "out" or "inout" dummy argument.
Another approach for argument "safety": you can also use the "value" attribute in the declaration of a dummy argument to essentially make a local copy of the argument and guarantee that the actual argument won't be altered.
Edit: As kemiisto pointed out, "contains" also makes the interface known. I don't like "contains" because the variable scoping ... all variables of the parent program are visible. Try this test code out:
PROGRAM contains_tst
INTEGER :: i, m
i = 21
m = 22
CALL test(m)
CONTAINS
SUBROUTINE test(j)
INTEGER, INTENT(IN) :: j
write (*, *) i, j
END SUBROUTINE test
END PROGRAM contains_tst