 |
» |
|
|
 |
Fortran 90 procedures are implemented
either as function subprograms or as subroutine subprograms. A function
subprogram returns a value, the function-result,
for use within an expression evaluation. Procedure categories |  |
Intrinsic
procedures are those available for use without any declaration or
definition. They are described in detail in Chapter 11. Intrinsic procedures provide a
way to incorporate into standard Fortran 90 the most common
computations important to scientific and engineering applications.
Standard Fortran 90 has 108 intrinsic functions and 5 intrinsic
subroutines. Table 12 lists the different categories of intrinsic
functions and gives the total number of intrinsic functions for
each category. Table 7-1 Categories of intrinsic functions Category | Total |
|---|
Conversion intrinsics | 16 | Array intrinsics | 17 | Inquiry and model intrinsics | 28 | Numeric computation | 26 | Character computation | 12 | Bit
computation | 9 |
Some intrinsic procedures are known as elemental;
that is, they can also take scalar arguments to produce a scalar
result, but they can accept conformable arrays as arguments, in
which case they operate on each array element separately and return
an array as a result. Several different intrinsic procedures can be called using
the same name when the actual arguments are of different kinds,
types and ranks. For example when using SQRT(x),
x can be of type real or complex, it
can be of any defined kind, and it can be an array of any of these
types, of any rank. The name used is a generic name
for a set of procedures, each of which accepts an argument of a
fixed kind, type, and rank. An
external procedure is a separately compilable
program unit whose name and any additional entry points have global
scope. A module procedure can appear only
within a module. Its name can be made available outside the scope
of its host only by use association. It is not otherwise accessible
outside of its host. An
internal procedure can appear only within
a main program, an external subprogram, or a module subprogram.
It cannot have additional entry points, and it is not accessible
outside its host. It appears between a CONTAINS
and END statement
of its host. Procedure use |  |
The following sections describe how to reference a procedure
subprogram: A
subroutine subprogram is referenced by using the CALL
statement specifying the subroutine name, one of its entry point
names, or when the subroutine is implementing an assignment operation. The syntax of the CALL
statement is: CALL subroutine-name [([actual-argument-spec-list])] |
- actual-argument-spec
is [keyword =] actual-argument - keyword
is dummy-argument - actual-argument
is one of: - alternate-return
is one of:
label is permitted in HP Fortran
90 in fixed source form only. Alternate returns are arguments
which permit control to branch to a particular label following the
call. label is the statement label of
an executable statement in the same scoping unit as the CALL
statement. A function subprogram is referenced by its name, by one of
its entry point names or by the operator defined by the function. The syntax of a function reference is: function-name ([actual-argument-spec-list]) |
where actual-argument-spec is as
above, except that an alternate return cannot be included. On
invocation, the calling program unit can identify actual arguments
that are then associated with dummy arguments in the procedure definition.
This is also applicable to subroutine subprograms. The
interface of a procedure is the information
required to compile a call to the procedure. This information includes
the characteristics of the dummy arguments and of the result for
a function procedure. It is explicit
if all of these characteristics are defined within the scope of
the reference. If they are not, the compiler may be able to make
sufficient assumptions about them and the interface is then implicit.
Under many circumstances an explicit interface is mandatory. Internal
procedures and module procedures always have an explicit interface. Explicit interfaces can be specified by means of an INTERFACE
block. An INTERFACE
block is also used to define the extended use of the standard operators,
to define new operators and to extend the definition of the assignment
operator. Additionally, it provides the capability of using a generic
name to reference any one of a set of procedures. The
user can define a generic name and code
several procedures to cater for the required different combinations
of argument characteristics. Then, by including the specifications
of these routines within an interface definition, use just the generic
name for referencing any of the procedures (the choice of procedure
being determined by matching actual and dummy arguments). The technique
can also be used to extend the selection of argument types. HP Fortran 90
provides two functions, %VAL
and %REF, that
can be used to communicate with procedures written in programming
languages other than Fortran that have different argument passing
conventions. These functions specify how an actual argument is to
be passed in a procedure reference. %VAL(a)
specifies that the value of the actual argument a
is to be passed to the called procedure. a
can be a constant, variable, array element, or derived-type component.
%VAL approximates
the default argument passing mechanism of the C programming language,
and it is to pass a Fortran object to a procedure written in C where
%VAL is typically
used. %REF(a)
specifies that the actual argument a
is to be passed as a reference to its value. This is how HP Fortran 90
normally passes arguments except those of type character; for each
character argument, HP Fortran 90 normally passes
both a reference to the argument and its length, with the length
being appended to the end of the actual argument list. Passing a
character argument using %REF
disables the passing of the character length argument.
These two routines may only be used in either an interface
block, or in the actual CALL
statement or function reference. For
information about %VAL and %REF, see the description of the CALL
statement in Chapter 10 and of the ALIAS directive in Chapter 14. The following example uses %VAL
and %REF in an
interface block: CALL fred(i) ! The value of i is passed to fred |
j = foo(i) ! i passed to foo by reference, |
! foo receives a reference to |
In the next example, %REF
and %VAL appear
in the actual procedure references: Procedure interfaces and interface blocks are described later
in this chapter. Procedure definition |  |
Functions and subroutinesFunctions and subroutines are defined in Fortran 90
by means of subprograms. A subroutine subprogram has the form: [internal-subprogram-part] |
A function subprogram has the form: [internal-subprogram-part] |
- internal-subprogram-part
is - internal-subprogram
is a subprogram without any internal-subprogram-part. - end-subroutine-statement
is END [SUBROUTINE [subroutine-name]] |
- end-function-statement
is END [FUNCTION [function-name]] |
Statements introducing proceduresThe SUBROUTINE
statement introduces a subroutine subprogram. The syntax for subroutine-statement
is: [RECURSIVE] SUBROUTINE subroutine-name [([dummy-argument-list])] |
The
FUNCTION statement
introduces a function subprogram. The syntax for function-statement
is: [prefix] FUNCTION function-name ([dummy-argument-list]) [RESULT (result-name)] |
Title not available (FUNCTION
statement) - prefix
is one of:
Dummy arguments are discussed in “Subprogram arguments”; actual arguments are described in “Procedure use”. The result-name
must be different from the function-name,
and must be given if the function is recursive. If there is a result
clause, the result-name must be used
as the result variable, otherwise the function name must be used. The
ENTRY statement
defines a procedure entry. Its syntax is: ENTRY entry-name ([dummy-argument-list]) [RESULT (result-name)] |
The RESULT
clause may appear only if the ENTRY
statement is in a function subprogram. ENTRY statements
can appear only within the execution part of a subprogram; they
provide additional names by which the subprogram can be invoked.
Execution will commence at the statement immediately following the
referenced ENTRY
statement, but the ENTRY
statement does not interrupt the sequencing of execution across
it. ENTRY statements
may not appear within an internal subprogram. When used in a function subprogram, all ENTRY statements should
return results of the same type, kind, and shape; otherwise they
should all return results that are scalars without the POINTER attribute
and which are of intrinsic numeric or logical type. Examples of the ENTRY
statement are given in Chapter 10. Internal
procedures are defined by internal subprograms in the internal subprogram
part of a main, external, or module program unit. Internal subprograms
can be recursive. The following restrictions apply to internal subprograms: They cannot have ENTRY
statements. They cannot be passed as arguments. Their names are local to the host. The interface of an internal procedure is explicit
in the host. Declarations in the host are inherited by the internal
subprogram, but can be overridden. They cannot be the host of another internal procedure.
Following is an example of an internal function: ! Start of external subprogram. |
! Reference to function av. |
! Start of internal subprogram. |
! References to intrinsic functions. |
An
internal or external procedure that directly or indirectly invokes
itself is recursive. Such a procedure
must have the word RECURSIVE
added to the FUNCTION
or SUBROUTINE
statement. If
both RECURSIVE
and a result clause are specified in the FUNCTION
statement , then the interface of the function being defined is
explicit within the subprogram. The following is a recursive function: RECURSIVE FUNCTION factorial (n) RESULT(r) |
If
an evaluation of a function with a scalar value can be expressed
in just one Fortran assignment statement, such a definition can
be included in the specification part of a main program unit or
subprogram. This definition is known as a statement function,
and is local to the scope in which it is defined. The syntax is: function-name (dummy-argument-list) = scalar-expression |
All dummy arguments must be scalars. All entities used in
the expression must have been declared earlier in the specification
part. A statement function can reference another statement function
that has already been declared. The name cannot be passed as a procedure-name
argument. The following example declartes and uses the statement function
vol: ! Definition, within the specification part |
! Reference to the statement function, from |
! within the same program unit. |
Returning to the calling unit |  |
When the END
statement of the subprogram is encountered, control will be returned
to the calling program unit. The RETURN
statement can be used to the same effect at any point within the
subprogram. The syntax of the RETURN
statement is: RETURN [scalar-integer-expression] |
When
alternate returns have been declared, the value of the scalar integer
expression determines which argument corresponds to the requested
return point. The dummy arguments corresponding to the alternate
returns must each be declared as an asterisk (*).
If the value of the expression is n,
then the return is to the labeled statement referred to by the actual
argument corresponding to the nth
dummy argument declared as an asterisk. Subprogram arguments |  |
Actual
arguments appear in a procedure reference and specify the actual
entities to be used by the procedure during its execution. Dummy
arguments are specified when the procedure is defined and are the
name by which the actual arguments are known within a procedure.
When a procedure is referenced during program execution, the actual
arguments become associated with the dummy arguments through argument
association. A dummy argument can be either a name or (if the subprogram
is a subroutine) *. A subprogram actual argument is one of: Arguments allow a calling program unit and a called subprogram
to communicate with each other. The calling unit provides a list
of actual arguments and the called subprogram
will have been declared with a list of dummy
arguments. If
no keyword=
component of an actual-argument-spec
is included in the reference, then each actual argument is assumed
to correspond with the dummy argument in the equivalent position
in the dummy argument list. The actual arguments may appear in any
order if the keyword option is used for all arguments. Actual arguments
without the keyword option may be followed by an argument with the
keyword option. However, an argument with the keyword option must
only be followed by other arguments with the keyword option. Dummy
arguments can be declared with the OPTIONAL
attribute. If they appear at the end of the dummy argument list,
the reference can omit any trailing arguments that are not required.
Otherwise, keywords must be provided to maintain an identifiable
correspondence. Example of argument correspondenceThe
intrinsic function SUM
(described in Chapter 11) has three arguments: array,
dim, and mask,
in that order, and dim and mask are optional arguments. The following
are valid references: The following is an invalid reference—the mask keyword
should have been specified: SUM(a,DIM=2,a.gt.0) ! Invalid |
Dummy and actual arguments must agree in kind, type, and usually
in rank—that is, both scalars, or both arrays of the same
dimensionality. An actual argument that is an expression or a reference
to a function procedure must match the type and kind of the dummy
argument. If
the dummy argument is a scalar, then the corresponding actual argument
must be a scalar, or scalar expression, of the same kind and type. If the dummy argument is a character variable and has assumed
length then it will inherit the length of the actual argument. Otherwise
the length of the actual argument must be at least that of the dummy
argument, and only the characters within the range of the dummy
argument can be accessed by the subprogram. The lengths may differ
only for default character types. The different sorts of Fortran 90 arrays are described
in Chapter 4. If
the dummy argument is an assumed-shape array, then the corresponding
actual argument must match in kind, type, and rank; the dummy argument
assumes its shape (the number of elements
in each dimension) from the actual argument, resulting in an element-by-corresponding-element
association between the actual and dummy arguments. If
the dummy argument has explicit shape or assumed size, the kind
and type of the actual argument must match but the rank need not,
as the elements are matched by sequence association.
That is, the actual and dummy arguments are each considered to be
a linear sequence of elements in storage without regard to rank
or shape, and corresponding elements in each sequence are associated
with each other. A consequence of this sequence association is that the overall
size of the actual argument must be at least that of the dummy argument,
and only elements within the overall size of the dummy argument
can be accessed by this subprogram. The following example illustrates sequence association. Assuming
that an actual array argument is declared thus: And that the corresponding dummy array argument is declared
thus: Then the following correspondence between elements of the
actual and dummy argument is achieved: d(1,1,1) <=> a(0,0)d(2,1,1) <=> a(1,0) |
When an actual argument and associated dummy argument are
default character arrays, they may be of unequal character length.
If this is the case, then the first character of the dummy and actual
arguments will be matched, and the successive characters, rather
than array elements, will be matched. The next example illustrates character sequence association. Assuming that an actual argument array is declared thus: and that the corresponding dummy array argument is declared
thus: then the following correspondence between elements of the
actual and dummy argument is achieved: d(1,1) <=> a(1,1)//a(2,1) |
d(2,1) <=> a(3,1)//a(1,2) |
d(2,3) <=> a(2,4)//a(3,4) |
An actual argument may be an array section, but passing an
array section to a nonassumed shape dummy argument may cause a copy
of the array section to be generated and is likely to result in
a degradation in performance. Derived-type dummy argumentThe
corresponding dummy and actual arguments of derived types are of
the same derived type if the structures refer to the same
type definition. Alternatively, they are of the same type if all
the following are true: They refer to different type definitions
with the same name. They both have the SEQUENCE
statement in their definition. The components have the same names and types and
are in the same order. None of the components is of a private type or is
of a type that has private access.
If
the dummy argument has the POINTER
attribute, the actual argument must also have the POINTER
attribute, and match in kind, type, and rank; the dummy argument
in the procedure then behaves as if the actual argument were used
in its place. If the dummy argument does not have the POINTER
attribute but the actual argument is a pointer, the argument association
behaves as if the pointer actual argument were replaced by its target
at the time of the procedure reference. If
a dummy argument of a procedure is used as a procedure name within
the procedure, then the actual argument must be the name of an appropriate
subprogram, and its name must have been declared as EXTERNAL
in the calling unit or defined in an interface block. Internal procedures,
statement functions and generic names may not
be passed as actual arguments. If the actual argument is an intrinsic procedure, then the
appropriate specific name must be used in the reference, and must
be declared as INTRINSIC
in the calling unit. Example DOUBLE PRECISION dsin,x,y,fun |
DOUBLE PRECISION FUNCTION fun(proc,y) |
If
a subroutine call or function reference would cause a data object
to be associated with two or more dummy arguments, then that data
object must not be (re)defined within the subroutine or function.
Consider the following example: c = 22.01 ! invalid definition of |
Both dummy arguments, c
and d, are associated
with the actual argument a.
The definition of a,
through the assignment to the dummy argument c,
is invalid. The above rule is extended to when the actual arguments
are overlapping sections of the same array. Similarly,
if a data object is available to a procedure through both argument
association and either use, host, or storage association, then the
data object must be defined and referenced only through the dummy
argument. In the following code, the data object a
is available to the subroutine as a consequence of argument association
and host association. The reference to a
directly in the subroutine is illegal. c = 22.01 ! valid definition of a |
d = 3.0*a ! reference to a directly |
To
enable additional checking to be performed on argument matching
and to avoid possible unwanted side effects, an INTENT
attribute can be declared for each dummy argument, which may be
specified as INTENT(IN),
INTENT(OUT) or
INTENT(INOUT). The values that may be specified for the INTENT
attribute have the following significance: IN
is used if the argument is not to be modified within the subprogram. OUT
implies that the actual argument must not be used within the subprogram
before it is assigned a value. INOUT
(the form IN
OUT is also permitted)
implies that the actual argument must be defined on entry and is
definable within the subprogram.
Interfaces |  |
The
interface to a procedure (referred to as the procedure interface)
is that information, about the procedure, which is pertinent when
that procedure is invoked. This information includes: The name of the procedure. The properties (type, kind, and attributes) of the
result, if the procedure is a function. The names, types, kinds, attributes, and order of
the dummy arguments of the procedure.
The procedure interface is said to be explicit if the above
information is available to a program unit containing a reference
to the procedure; when the above information is not known, the procedure
interface is implicit. In FORTRAN 77 all procedure interfaces
are implicit, giving no way to ensure that the actual arguments
supplied in a procedure reference match the dummy arguments within
the procedure itself. In Fortran 90 procedure interfaces
can be either implicit or explicit. A number of new Fortran 90 features, as listed below,
require that the procedures involved have explicit procedure interfaces
available within the scoping units invoking them. An explicit procedure
interface is required when: The procedure reference uses the keyword
form of an actual argument. The procedure has OPTIONAL
arguments. Any dummy argument is an assumed-shape array or
pointer. The result of the procedure is an array or pointer. The procedure is a character function, the length
of which is determined dynamically. The procedure reference is to a generic name. The procedure reference is a consequence of a user-defined
operator function or operation. The
procedure reference is a consequence of a user-defined assignment.
Even where an explicit procedure interface is not required,
making a procedure interface explicit allows the compiler to check
the validity of references to the procedure. In Fortran 90, all procedure interfaces are implicit
except for procedures which are: Intrinsic procedures - the interface
of every intrinsic procedure is explicit. Internal procedures - the interface of an internal
procedure is explicit within its host. Module procedures - the interface of a module procedure
is explicit within a program unit using the module, and within the
module itself. Recursive functions which specify a result clause
- the interface of such a function is explicit within the function
itself. External procedures whose interfaces have been made
explicit by the provision of an interface block.
When
an external procedure (one which is outside the prevailing scope)
or a dummy procedure is referenced, it is sometimes necessary for
its interface to be made explicit. This is achieved by the provision
of an interface block which is accessible to the scoping unit containing
the procedure reference. An interface block can also be used to: Define a generic procedure name,
specify the set of procedures to which the generic name applies,
and make explicit the interfaces of any external procedures contained
within the set. Define a new operator or extend an already defined
operator, specify the set of functions which implement the operator,
and make the interfaces of any of these functions, which are external,
explicit. Define new defined assignment operations,
specify the set of subroutines to which to implement these operations,
and make the interfaces of any of these subroutines, which are external,
explicit.
An
explicit interface is described by an interface block, which appears
in the specification part of the programming unit containing the
procedure reference. An interface block may appear in any program
unit, except a block data program unit. The syntax for an interface-block is: [MODULE PROCEDURE module-procedure-name-list] |
- generic-spec
is one of: OPERATOR (operator)ASSIGNMENT (=) |
- generic-name
is the name of the generic procedure that is referenced
in the subprogram containing the interface block - operator
is one of the Fortran 90 unary or binary intrinsic
operators, or a user-defined unary or binary operator of the form: - interface-body
is or
The
MODULE PROCEDURE
statement is permitted in an interface block only if there is a
generic-spec present. In the following example, the procedure interface for the
function av is
made explicit by the inclusion of the interface block in the main
program. Example ! External function av with one assumed-shape |
Generic names and proceduresThe concept of generic names and procedures was introduced
in Fortran with the provision of generic intrinsic procedures. In
Fortran 90, this concept is extended to allow user-defined generic
procedures. Two or more procedures are said to be generic if they can
be referenced with the same name; the name that the procedures may
be referenced by is the generic name. A generic name is defined by an interface block containing
a generic-spec and the specifications
of the procedures which may be invoked by referencing the generic
name. The procedure specifications in the interface block must be
distinguishable from each other in one or more of the following
ways: The number of dummy arguments differ. Dummy arguments, from the specific procedure specifications,
that occupy the same position in the argument lists differ in type,
kind, or rank. The name of a dummy argument differs from the names
of the other dummy arguments in dummy argument lists of other procedure
specifications, or all dummy arguments with the same name differ
in either type, kind, or rank.
There may be more than one interface block with the same generic
name, but the procedure specifications in all such interface blocks
must be distinguishable by the above criteria. When a generic name is referenced it must be possible to determine
to which of the specific procedures the generic name refers; the
generic reference must resolve to a unique
specific procedure name. Selection of the specific procedure is
based on the properties of the actual argument list, including: The number of actual arguments. The type, kind, and rank of each actual argument. The argument keyword, if supplied, of an actual
argument.
The specific procedure whose dummy argument list matches the
actual argument list is selected and invoked from the list of procedure
specifications contained in the interface block that defines the
generic name. The dummy argument list of exactly one of the procedure
specifications contained in the interface block must match the actual
arguments in the reference of the generic name. The MODULE
PROCEDURE statement
can be used to extend the list of procedure specifications that
comprises the interface block, by naming procedures that are accessible
to the program unit containing the interface block. In the MODULE
PROCEDURE statement
only the specific names of the procedures are given as their procedure
interfaces are already explicit. The MODULE
PROCEDURE statement
may only appear in an interface block that has a generic specification,
and the interface block must either be in the module containing
the definitions of the named procedures or, in a program unit in
which the procedures are accessible through use association. In the following example, it is assumed that two subroutines
have been coded for solving linear equations: rlineq
for when the coefficients are real, and zlineq
for when the coefficients are complex. A generic name, lineq,
is declared as follows and then used for either reference. SUBROUTINE rlineq(ra,rb,rx) |
REAL,DIMENSION(:,:) :: ra |
REAL,DIMENSION(:) :: rb,rx |
SUBROUTINE zlineq(za,zb,zx) |
COMPLEX,DIMENSION(:,:) :: za |
COMPLEX,DIMENSION(:) :: zb,zx |
The
OPERATOR (operator)
generic specification can be used to either define a new user-defined
operator symbol, or to extend the behavior of an already defined
or intrinsic operator. When
the OPERATOR
(operator) generic specification is present
in the INTERFACE
statement, the procedure specifications that immediately follow
must only describe function subprograms. The functions described
are those that are to be used to implement the operator for various
type, kind, and rank combinations of operand. These functions must
have only one or two mandatory arguments, which correspond to the
operand(s) of a unary or binary operator. The functions return the
result of an expression of the form: or operand1 operator operand2 |
as appropriate. Each dummy argument of the functions described
in the interface block must have the INTENT(IN)
attribute. If operator is one of the Fortran 90 intrinsic
operators, then each of the specified functions must take the same
number of arguments as the intrinsic operator has operands, and
the arguments must be distinguishable from those normally associated
with the intrinsic operation. Argument keywords must not be specified in a reference to
a user-defined operator function when the operator syntax, rather
than the name of the specific function, is used in an expression. An interface block that defines or extends an operator is
analogous to defining a generic procedure name, with the operator
being the generic name. Similarly a reference to a user-defined
operator must resolve to a unique specific function name. The selection
of the function is accomplished by matching the number, type, kind,
and rank of the operand(s) with the dummy argument lists of the
function specifications contained in the interface block. As with
generic names exactly one such specification must match the properties
of the operands, and the function whose specification does match
is selected and invoked. See the examples in the next section. The
ASSIGNMENT(=)
option allows you to specify one or more subroutines that extend
the assignment operation. Each subroutine must have only two mandatory
arguments; the first argument can have either the INTENT(OUT)
or the INTENT(INOUT)
attribute ; the second argument must have the INTENT(IN)
attribute. The first argument corresponds to the variable on the
left-hand side of the assignment statement, and the second to the
expression on the right-hand side. In a similar manner to generic names and defined operators,
defined assignment must resolve to a unique specific subroutine.
The subroutine whose dummy arguments match the left and right-hand
sides of the assignment statement in all of kind, type, and rank
is selected and invoked from the list of subroutine specifications
contained in the defined assignment interface block. The following example illustrates the definition of a user-defined
unary operator, .eigenvalues.
, that, when applied to an object of type matrix,
computes its eigenvalues: INTERFACE OPERATOR (.eigenvalues.) |
find_eigenvalues(matrix_1) |
TYPE (matrix), INTENT(IN) :: matrix_1 |
END FUNCTION find_eigenvalues |
TYPE (matrix) :: a; TYPE (vector) :: b |
! Compute the eigenvalues of a. |
The next example extends the *
operator and assignment in order to work with entities of derived
types. MODULE PROCEDURE polar_mul, interval_mul |
MODULE PROCEDURE assign_polar_to_complex |
TYPE (interval) :: v1, v2, v |
! A defined operation and an intrinsic |
! A defined operation and an defined assignment. |
|