The three options for the "intent" of an argument are:
REAL, INTENT(IN) :: X, Y
REAL, INTENT(OUT) :: Z
If X and Y have been declared as in this
example, any attempt to change the
value of X or Y within the subprogram,
would result in an error message. Such a warning would
occur since any change in an argument within a subprogram
in Fortran means that the change also affects the corresponding
actual argument in the calling segment. In this case, since both
X and Y have been designated as
having intent IN, they are unable
to convey new values out from the subprogram, and
hence any attempt to change their values (and assign them new values)
should result in an error message.
An argument with intent OUT cannot have any input value. It receives a value within the subprogram and conveys the new value back to the calling program.
An argument with attribute POINTER (see Chapter 17) is not allowed to have an intent associated with it.
SUBROUTINE SOLVE(A, B, C, N)
REAL, OPTIONAL :: A, C
REAL :: B
INTEGER, OPTIONAL :: N
When invoking this subprogram, with all its arguments, it may
be invoked as usual, that is,
CALL SOLVE(A, B, C, N)
When omitting certain arguments, one may use the
"positional" argument association up to the first argument that is
omitted. (In other words, we assume that the
first actual argument corresponds to the first "dummy" argument,
etc.)
After that point, one needs to indicate (by explicitly
indicating the "dummy" argument name) which actual argument
corresponds to which "dummy" argument. For example, if the third
argument (i.e., C)
were to be omitted from a call of SOLVE, one could
write
CALL SOLVE(A,B,N=N2)
or one could explicitly indicate the dummy argument as a keyword
for every argument, for example,
CALL SOLVE(A=A,B=B,N=N2)
One may even rearrange the order of the actual arguments if
one includes the keywords, for example,
CALL SOLVE(B=B,N=N2,A=A)
NOTE: When using a subprogram with optional arguments,
an explicit interface (cf. section 9.6)
must be included.
The use of optional arguments means that some method needs to exist to determine whether the argument has actually been passed to the subprogram (and thus, whether the subprogram needs to provide, for example, a default value for the missing argument). This method is provided by the intrinsic logical function PRESENT which takes any dummy optional argument of the subprogram as its own argument. If the argument has been omitted, the function returns a value of .FALSE. Otherwise the function returns .TRUE. when a value has been passed.
Thus, to provide the optional argument C (in the example above) with a default value if it should be omitted, one could use code such as this:
IF (.NOT.(PRESENT(C))) THEN
C = 1.0
END IF
It is sometimes necessary to create several subprograms which generally do the same operation, but each having arguments of different data types. Standard rules require that each of these subprograms be given a different subprogram name. But it can be helpful to be able to invoke any of them by the same "generic" name and have the compiler choose the appropriate subprogram based on the data type of the arguments.
Fortran-90/95/2003 permits a programmer to group different (yet similar) subprograms together and assign them a "generic" name. This may be done in one of two ways.
SUBROUTINE SWAP_REAL(A,B)
REAL :: A, B, TEMP
TEMP = A; A = B; B = TEMP
END
!
SUBROUTINE SWAP_INT(A,B)
INTEGER :: A, B, TEMP
TEMP = A; A = B; B = TEMP
END
In the main program, one can invoke both of these procedures
using a generic name, e.g., SWAP, if one includes the
following interface in the declaration part of the main program.
INTERFACE SWAP
SUBROUTINE SWAP_REAL(A,B)
REAL :: A, B
END SUBROUTINE
!
SUBROUTINE SWAP_INT(A,B)
INTEGER :: A, B
END SUBROUTINE
END INTERFACE
By assigning the name SWAP to the interface and
including references to the two subprograms, the generic
name SWAP becomes a way to access either of the
two specific subprograms, and the correct one is chosen
by the compiler as needed, based on the data type of the arguments.
MODULE SWAP_MOD
INTERFACE SWAP
MODULE PROCEDURE SWAP_REAL, SWAP_INT
END INTERFACE
CONTAINS
SUBROUTINE SWAP_REAL(A,B)
REAL :: A, B, TEMP
TEMP = A; A = B; B = TEMP
END
!
SUBROUTINE SWAP_INT(A,B)
INTEGER :: A, B, TEMP
TEMP = A; A = B; B = TEMP
END
END MODULE
Note the use of the keyword PROCEDURE in the
interface.
The calling program segment would need to include
USE SWAP_MOD
rather than the more detailed interface shown above.
The calling program segment could then also invoke
either procedure via the general name of SWAP.
This page is maintained by Dennis C. Smolarski, S.J.
dsmolarski@math.scu.edu
© Copyright 1999-2005 Dennis C. Smolarski, S.J., All rights reserved.
Last changed: 23 June 2005.