



External Procedures FUNCTION statement. They are executed whenever the corresponding
function is used as an operand in an expression.
SUBROUTINE statement. They are executed in response to a CALL
statement.END statement. Any
other statements (except PROGRAM or BLOCK DATA statements) may be used within
the program unit.
There are two statements provided especially for use in external procedures. The
SAVE statement ensures that the values of local variables and arrays are preserved
after the procedure returns control to the calling unit: these values will then be
available if the procedure is executed subsequently. The RETURN statement may be
used to terminate the execution of the procedure and cause an immediate return to
the control of the calling unit. Execution of the END statement at the end of the
procedure has exactly the same effect. Both of these are described in full later in the
section.
Most Fortran systems also allow external procedures to be specified in languages other than Fortran: they can be called in the same way as Fortran procedures but their internal operations are, of course, beyond the scope of this book.
It is best to think of the subroutine as the more general form of procedure; the external function should be regarded as a special case for use when you only need to return a single value to the calling unit.
Here is a simple example of a procedure which converts a time of day in hours, minutes, and seconds into a count of seconds since midnight. Since only one value needs to be returned, the procedure can have the form of an external function. (In fact this is such a simple example that it would have been possible to define it as a statement function.)
*TSECS converts hours, minutes, seconds to total seconds. REAL FUNCTION TSECS(NHOURS, MINS, SECS) INTEGER NHOURS, MINS REAL SECS TIME = ((NHOURS * 60) + MINS) * 60 + SECS END |
(12,30,0.0)
are known as the actual arguments of the function; these values are transferred to the
corresponding dummy arguments
(NHOURS, MINS, SECS)
of the procedure before it is executed. In this example the argument list is used
only to transfer information into the function from outside, the function
name itself returns the required value to the calling program. In subroutines,
however, there is no function name to return information but the arguments can
be used for transfers in either direction, or both. The rules permit them
to be used in this more general way in functions, but it is a practice best
avoided.
The next example performs the inverse conversion to the TSECS function. Since it has to return three values to the calling program unit the functional form is no longer appropriate, and a subroutine will be used instead.
*Subroutine HMS converts TIME in seconds into hours, mins,secs. SUBROUTINE HMS(TIME, NHOURS, MINS, SECS) REAL TIME, SECS INTEGER NHOURS, MINS NHOURS = INT(TIME / 3600.0) SECS = TIME - 3600.0 * NHOURS MINS = INT(SECS / 60.0) SECS = TIME - 60.0 * MINS END |
CALL HMS(45000.0, NHRS, MINS, SECS) WRITE(UNIT=*, FMT=*) NHRS, MINS, SECS |
Each program unit has its own independent set of symbolic names and labels.
Type statements and IMPLICIT statements may be used to specify their data
types.
External procedures can themselves call any other procedures and these may call others in turn, but procedure are not allowed to call themselves either directly or indirectly; that is recursive calling is not permitted in Fortran.
Information can be transferred to and from an external procedure by any of three methods.
It is not necessary to know how the Fortran system actually transfers information from one procedure to another to make use of the system, but the rules governing the process are somewhat complicated and it may be easier to understand them if you appreciate the basis on which they have been formulated. The rules in the Fortran Standard are based on the assumption that the address of an actual argument is transferred in each case: this may or may not be true in practice but the properties will be the same as if it is.
This means that when you reference a dummy variable or assign a new value to one you are likely to be using the memory location occupied by the actual argument. By this means even large arrays can be transferred efficiently to procedures. A slight modification of this system is needed for items of character type so that the length of the item can be transferred as well as its address.
When a function reference or CALL statement is executed any expressions in
the argument list are evaluated; the addresses of the arguments are then
passed to the procedure. When it returns control this automatically makes
updated values available to the corresponding items in the actual argument
list.
The rules of Fortran allow functions to have side-effects, that is to alter their actual arguments or to change other variables within common blocks. Functions with side-effects cannot be used in expressions where any of the other operands of the expression would be affected, nor can they be used in subscript or substring references when any other expression used in the same references would be affected. This rule ensures that the value of an expression cannot depend arbitrarily on the way in which the computer chooses to evaluate it.
There are also restrictions on functions which make use of input/output statements even on internal files: these cannot be used in expressions in other I/O statements. This is to avoid the I/O system being used recursively.
By far the best course is to use the subroutine form for any procedure with side-effects.