I have a few questions about the INTENT
of variables within a subroutine in Fortran. For example, several weeks ago, I posted a question about a different Fortran topic (In Fortran 90, what is a good way to write an array to a text file, row-wise?), and one of the replies included code to define tick
and tock
commands. I have found these useful to time my code runs. I have pasted tick
and tock
below and used them in a simple example, to time a DO
loop:
MODULE myintenttestsubs
IMPLICIT NONE
CONTAINS
SUBROUTINE tick(t)
INTEGER, INTENT(OUT) :: t
CALL system_clock(t)
END SUBROUTINE tick
! returns time in seconds from now to time described by t
REAL FUNCTION tock(t)
INTEGER, INTENT(IN) :: t
INTEGER :: now, clock_rate
CALL system_clock(now,clock_rate)
tock = real(now - t)/real(clock_rate)
END FUNCTION tock
END MODULE myintenttestsubs
PROGRAM myintenttest
USE myintenttestsubs
IMPLICIT NONE
INTEGER :: myclock, i, j
REAL :: mytime
CALL tick(myclock)
! Print alphabet 100 times
DO i=1,100
DO j=97,122
WRITE(*,"(A)",ADVANCE="NO") ACHAR(j)
END DO
END DO
mytime=tock(myclock)
PRINT *, "Finished in ", mytime, " sec"
END PROGRAM myintenttest
This leads to my first question about INTENT
(my second question, below, is about subroutine or function arguments/variables whose INTENT is not explicitly specified):
To start the timer, I write
CALL tick(myclock)
, wheremyclock
is an integer. The header of the subroutine isSUBROUTINE tick(t)
, so it accepts the dummy integert
as an argument. However, inside the subroutine,t
is given INTENT(OUT):INTEGER, INTENT(OUT) :: t
. How can this be? My naive assumption is that INTENT(OUT) means that the value of this variable may be modified and will be exported out of the subroutine--and not read in. But clearlyt
is being read into the subroutine; I am passing the integermyclock
into the subroutine. So sincet
is declared as INTENT(OUT), how can it be thatt
seems to also be coming in?I notice that in the function
tock(t)
, the integer variablesnow
andclock_rate
are not explicitly given INTENTs. Then, what is the scope of these variables? Arenow
andclock_rate
only seen within the function? (Sort of like INTENT(NONE) or INTENT(LOCAL), although there is no such syntax?) And, while this is a function, does the same hold true for subroutines? Sometimes, when I am writing subroutines, I would like to declare "temporary" variables like this--variables that are only seen within the subroutine (to modify input in a step preceding the assignment of the final output, for example). Is this what the lack of a specified INTENT accomplishes?
I looked in a text (a Fortran 90 text by Hahn) and in it, he gives the following brief description of argument intent:
Argument intent. Dummy arguments may be specified with an intent attribute, i.e. whether you intend them to be used as input, or output, or both e.g.
SUBROUTINE PLUNK(X, Y, Z)
REAL, INTENT(IN) :: X
REAL, INTENT(OUT) :: Y
REAL, INTENT(INOUT) :: Z
...
If intent is IN, the dummy argument may not have its value changed inside the subprogram.
If the intent is OUT, the corresponding actual argument must be a variable. A call such as
CALL PLUNK(A, (B), C)
would generate a compiler error--(B) is an expression, not a variable.
If the intent is INOUT, the corresponding actual argument must again be a variable.
If the dummy argument has no intent, the actual argument may be a variable or an expression.
It is recommended that all dummy arguments be given an intent. In particular, all function arguments should have intent IN. Intent may also be specified in a separate statement, e.g. INTENT(INOUT) X, Y, Z.
The above text seems not even to mention argument/variable scope; it seems to be mainly talking about whether or not the argument/variable value may be changed inside the subroutine or function. Is this true, and if so, what can I assume about scope with respect to INTENT?