Chapter 4. Using Procedures

Procedures help to structure a problem solution into understandable segments. This chapter describes the details for constructing and using procedures in Fortran.

Procedure Terms and Concepts

This section describes some of the basic terms and concepts associated with Fortran procedures.

Procedure Terms

A procedure can take two basic forms in a Fortran program: a subroutine and a function. These two forms are very similar except in the way they are invoked.

Subroutines

A subroutine is a procedure whose purpose is to perform an action, such as modifying a set of arguments and/or global variables, or performing input/output (I/O). Typically, a subroutine is invoked with a CALL statement, but Fortran also provides an additional form of subroutine reference: the defined assignment. A subroutine can be used to define a new form of assignment, one that is different from those intrinsic to Fortran. Such subroutines are invoked with assignment syntax (using the = symbol) rather than with the CALL statement.

Functions

The purpose of a function is to provide a value needed in an expression. A function is invoked as an expression operand, and the result is used as the value of that operand. In addition, a Fortran function can be used to define a new operator or extend the meaning of an intrinsic operator symbol; such a function is invoked by the appearance of the new or extended operator in the expression along with the appropriate operand(s). For example, an interpretation for the operator + can be defined for logical operands. This extends the + operation's intrinsic definition because the intrinsic definition of + involves only numeric operands.

Function Results

The main difference between a subroutine and a function is that there is a function result value associated with a function. More precisely, there is a result value associated with any particular execution or call to a function. This result can be of any type, including derived type, and it can be array-valued. The RESULT option in the FUNCTION statement can be used to give the result a different name than the function name. The RESULT clause is not required for a recursive function that calls itself directly unless the function result is array-valued.


Note: If a function invokes itself directly, the Fortran standard requires that a RESULT clause be specified.


External Procedures

External procedures are stand-alone subroutines and functions that are not part of any other program unit. They can share information, such as data and procedures through argument lists, modules, and common blocks, but otherwise they do not share information with any other program unit. They can be developed, compiled, and used completely independently of other procedures and program units. In fact they need not even be written in Fortran.

Intrinsic Procedures

Fortran contains intrinsic procedures such as sine and cosine. Intrinsic procedures are available to any Fortran program unit automatically. There are over 100 intrinsic procedures in Fortran, and the CF90 and MIPSpro 7 Fortran 90 compilers include several additional procedures as extensions. These procedures are described in Chapter 5, “Intrinsic Procedures”.

Many of the intrinsic procedures are generic. The generic properties (when two or more procedures share the same name) of an intrinsic procedure can be extended and the automatic availability of an intrinsic procedure can be overridden explicitly by an EXTERNAL statement or a procedure interface block.

Many intrinsic procedures can be called elementally. In these cases an array is supplied instead of a scalar for an actual argument. The computation is applied element-by-element to those arguments and returns a conformable array result. User-defined procedures cannot be called elementally.

Internal Procedures

Internal procedures are defined within other procedures. The procedure that contains an internal procedure is called the host of the internal procedure. An internal procedure can be either a subroutine or a function and appears between the CONTAINS and END statements of its host. An internal procedure is local to its host and inherits the host's environment through host association.

Module Procedures

Module procedures are defined within module program units. A module procedure can be either a subroutine or a function and appears between the CONTAINS and END statements of its host module. A module procedure inherits the host module's environment through host association. A module procedure can be PRIVATE to the module, and hence available only within the module, or it can be PUBLIC.

Statement Functions

Statement functions are one-statement function definitions in the specification part of a program unit other than a module or a block data program unit. Their functionality is extended and essentially superseded by internal functions in Fortran.

Procedure Entry

Normally, one procedure is associated with a procedure subprogram. However, a procedure subprogram, which is a syntactic entity, can define any number of conceptual procedures. The name of the procedure subprogram identifies one procedure associated with that subprogram. An ENTRY statement can be used to specify and identify an additional procedure associated with that subprogram. These statements are procedure entries, and each defines an additional procedure. This technique is often used in external procedure subprograms to define different actions involving the data environment of the subprogram. The classic example is the use of the same subprogram to define both the SIN and COS functions, because COS(x)=SIN/2-x). This sort of data sharing is provided by host association for internal and module procedures; therefore, procedure entries are not needed for internal and module procedures. Procedure entries are not permitted for internal procedures, although they are permitted in module procedures.

Procedure Reference

Procedure reference is the term given to the appearance of a procedure name in a program in such a way that causes the procedure to be executed. This is also termed calling or invoking the procedure. In most cases reference is used in this chapter, although occasionally call or invoke is used. These terms are used for both functions and subroutines. When a procedure is invoked, it suspends execution of the program making the call while the procedure is executed. When procedure execution is completed, the invoking program resumes execution.

A subroutine reference is a standalone action in the form of a CALL statement. In some cases, the call can take the form of an assignment statement.

A function reference occurs as part of an expression when the name of the function and its argument list appear as a primary in the expression. In some cases, a function reference can take the form of a unary or binary operation involving an operator with the arguments as its operands.

Actual Arguments

Actual arguments appear in a procedure reference and specify the actual entities to be used by the procedure during its execution. These can be variables, for example, with different values for each reference. Some arguments are used as input values, others are variables that receive results from the procedure execution, and some can be both.

Dummy Arguments

Dummy arguments are the names by which the actual arguments are known inside a procedure. You must specify these names when the procedure is defined and use them to represent arguments in computations in the procedure. When the procedure is referenced during program execution, the actual arguments in the reference become associated with the dummy arguments through argument association. If the procedure interface is explicit, a call to the procedure can use the dummy argument names as actual argument keywords.

Alternate Return

Alternate returns are special arguments allowed only in subroutines. They permit control to branch immediately to some spot other than the statement following the call. The actual argument in an alternate return is the label of the statement to which control should be transferred. This is frequently used in accommodating error exits from the subroutine. Alternate returns are an obsolescent feature, so control structures, such as IF and CASE constructs, should be used to achieve the desired control.

Dummy Procedures

Dummy argument names can be treated within the procedure definition as procedure names. That is, they can be used as procedure names in procedure references; this accommodates procedure passing. The associated actual argument for a dummy procedure must be the name of an actual procedure. The exceptions are that internal procedures, statement functions, and generic intrinsic names cannot be used as actual arguments.

Non-Fortran Procedures

Procedure definitions can be written in a language other than Fortran. As long as all references to such a procedure are consistent in terms of the properties of the interface to this procedure, the calling program remains standard conforming. It may not be portable, however, because the non-Fortran procedure or its method of argument communication might differ across implementations. The only way to guarantee consistent interfaces across implementations is to write all procedures in standard Fortran.

Argument Association

The term argument association refers to the matching up of data across procedure boundaries; that is, matching data sources being passed from the calling side with the appropriate receivers in the called procedure. One helpful image of this matching up is the plug/socket analogy in “Type, Kind, and Rank Matching”.

The term argument association refers first to the overall concept that such a matching up (or association) must take place in order to use procedures and second to the rules governing the matchups as described in “Argument Association”.

Recursion

Fortran procedures can be recursive. A procedure involved in either direct or indirect recursion must have the keyword RECURSIVE added to the FUNCTION or SUBROUTINE statement of the procedure definition.

Data initialization implies use of the SAVE attribute. For recursive procedures that have local data-initialized variables, each layer of recursion shares a single copy of the variable and initialization takes place only once, at the outset of program execution.

Host and Use Association

A procedure can access information specified outside its own scope of definition in the following ways:

Host association applies to a procedure defined (contained) within another (host) program unit. A host can be a main program, module program unit, external procedure, or module procedure. Data and procedure entities specified in or accessible to the host are accessible to the contained procedure through host association. The rules for host association are very similar to the scoping rules of typical block-structured languages, such as Pascal. The main difference is that the Fortran host association rules must take into account implicit as well as explicit declarations.

Use association applies to procedures and program units containing USE statements. All public entities of a module are available to a using procedure through use association, although the USE...ONLY mechanism can limit accessibility as the programmer desires. Use association allows shared data and procedure entities to be gathered together in a central place, with selective access to and hiding of these entities as appropriate in the specific situation.

Implicit and Explicit Interfaces

The interface to a procedure is the collection of names and attributes of the procedure and its arguments. When this information is not made available explicitly to the calling program, the interface is said to be implicit to the calling program. In this case the interface information is assumed by the calling program from the properties of the procedure name and actual arguments in the procedure call. With implicit interfaces, the compiler assumes that the programmer has specified a valid procedure call and has correctly matched actual argument and dummy argument data types, and so on. For array arguments, element sequence association is assumed. For pointer arguments, the target is passed. External procedures and statement functions have implicit interfaces. Note that an implicit interface prohibits the use of generic references and argument keywords because there are no such mechanisms to describe these characteristics.

A procedure interface is said to be explicit if the interface information is known at the point of call and does not have to be assumed. In this case the compiler can check and guarantee the validity of the call. Intrinsic procedures have explicit interfaces. The explicit nature of the intrinsic procedure interfaces, for example, permits generic intrinsic functions and keyword calls. The compiler can, based on the type of the actual argument, generate a call to the correct specific intrinsic function, because the compiler has explicit interface information for all of the intrinsic functions.

The interface block allows optional explicit specification of external procedure interfaces and is described later in this chapter.

Several Fortran features require explicit interfaces in order to allow correct and efficient procedure calls. These include optional arguments, calls using argument keywords, user-defined operations, user-defined assignment, and user-defined generic procedures. For more information on explicit interfaces, see “Explicit Interfaces”.

Subroutines

A subroutine defines a complete process and is self-contained. It has an initial SUBROUTINE statement, a specification part, an execution part that comprises the algorithm, any internal procedures that perform ancillary processes, and an END statement. When a subroutine is invoked, its execution begins with the first executable construct in the subroutine. Data objects and other entities may be communicated to and from the subroutine through argument association, host association, use association, or common storage association.

Subroutine Definition

The general format of an external, module, or internal subroutine is as follows:

[prefix] SUBROUTINE subroutine_name[([dummy_arg_list])]
[specification_part]
[execution_part]
[internal_subprogram_part]
END [ SUBROUTINE [subroutine_name]]

This format contains entities and statements that are defined as follows:

 

subroutine_subprogram

is

subroutine_stmt
[specification_part]
[execution_part]
[internal_subprogram_part]
end_subroutine_stmt

 

subroutine_stmt

is

[prefix] SUBROUTINE subroutine_name[ ([dummy_arg_list]) ]

 

prefix

is

prefix_spec[prefix_spec] ...

 

prefix_spec

is

RECURSIVE

  

or

PURE

  

or

ELEMENTAL

 

dummy_arg

is

dummy_arg_name

  

or

*

 

end_subroutine_stmt

is

END [ SUBROUTINE [subroutine_name]]

A dummy_arg is either a dummy argument name or an asterisk (*), where the asterisk designates an alternate return. When a subroutine is executed, the dummy arguments become associated with the actual arguments specified in the call (see “Argument Association”, for more information on this).

The following examples show SUBROUTINE statements:

SUBROUTINE CAMP(SITE)
SUBROUTINE TASK()
SUBROUTINE INITIALIZE_DATABASE
SUBROUTINE LIGHT(INTENSITY, M, *)
RECURSIVE SUBROUTINE YKTE(Y, KE)

The following example shows a subroutine subprogram:

SUBROUTINE TROUT(STREAM, FLY)
   CHARACTER*10 STREAM
   INTENT(IN) FLY
   STREAM = . . .
      . . .
END SUBROUTINE TROUT

If the END statement contains a subroutine name, it must be the same name as that in the SUBROUTINE statement.

An internal subroutine must not contain an internal subprogram part. An internal subroutine must not contain ENTRY statements.

In an internal or module subroutine, the END statement must be of the following form because the keyword SUBROUTINE is required:

END SUBROUTINE [subroutine_name]

The use of alternate returns is an obsolescent feature.

The following rules apply to the subroutine prefix:

  • The prefix can contain no more than one of each type of prefix_spec. For example, you cannot specify PURE twice in a prefix.

  • If you specify ELEMENTAL or PURE, the subroutine itself must conform to the rules governing elemental or pure procedures. See “Pure Procedures”, for information on pure procedures. See “Elemental Procedures”, for information on elemental procedures.

  • When a subroutine calls itself either directly or indirectly, you must specify RECURSIVE.

Dummy argument attributes can be specified explicitly in the body of the subroutine or may be declared implicitly. Each dummy argument is a local variable of the subroutine; therefore, its name must be different from that of any other local variable in the subroutine.

The INTENT attribute can be specified for the dummy arguments of the subroutine, but an INTENT attribute cannot be specified for a dummy pointer or a dummy procedure.

The PRIVATE and PUBLIC attributes must not be specified in a subroutine.

Subroutine Reference

To use or invoke a subroutine, place a CALL statement or defined assignment at that point in a program where the process the subroutine performs is needed. A subroutine invocation specifies the arguments to be used and the name of the subroutine.

A subroutine reference is defined as follows:

 

call_stmt

is

CALL subroutine_name[ ([actual_arg_spec_list]) ]

 

actual_arg_spec

is

[keyword = ]actual_arg

 

keyword

is

dummy_arg_name

 

actual_arg

is

expr

 

 

or

variable

 

 

or

procedure_name

 

 

or

alt_return_spec

 

alt_return_spec

is

* label

Each actual_arg is associated with the corresponding dummy argument, as described in “Argument Association”, by its position in the argument list or the name of its keyword. A variable is a special case of expression in the context of an actual_arg; a variable may be associated with dummy arguments used with any intent (IN, OUT, INOUT), whereas other forms of expressions must be associated either with dummy arguments with intent IN or dummy arguments that do not have an INTENT attribute.

Positional arguments must appear first in the argument list if both positional and keyword arguments are used in the same actual_arg_spec_list. Once the first keyword is used, the rest of the arguments must be keyword arguments.

Exactly one actual_arg is associated with each nonoptional dummy argument. For an optional dummy argument, the actual_arg may be omitted.

The keyword is the name of the dummy argument in the explicit interface for the subroutine. If a keyword is present, the actual_arg is associated with the dummy argument with that keyword name.

If the keyword is omitted, it must be omitted from all preceding actual_arg s in that argument list. If no keyword is used, the arguments all have a positional correspondence.

The label in the alternate return specifier must be a branch target in the same scoping unit as the CALL statement.

An actual_arg must not be the name of an internal procedure or statement function.

An actual_arg associated with a dummy procedure must be the specific name of a procedure. (There may be an identical generic name, but it is the procedure with that specific name that is passed.) Certain specific intrinsic function names must not be used as actual_args; see the Intrinsic Procedures Reference Manual, for more information on this.

If a reference to a pure procedure has an actual_arg that is a procedure_name, the actual_arg must be the name of a pure procedure.

A reference to an elemental subroutine is an elemental reference if all actual arguments corresponding to INTENT(OUT) and INTENT(INOUT) dummy arguments are arrays that have the same shape and if the remaining actual arguments are conformable with them.

Example of subroutine references:

      CALL TYR(2.0*A, *99) ! SUBROUTINE TYR (R, *)
      . . .
99    . . .                       ! error recovery
      CALL TEST(X = 1.1, Y = 4.4) ! SUBROUTINE
                                  !   TEST (Y, X)

In the first example, an alternate return to statement 99 in the calling program unit is the last argument. Keyword arguments are used for X and Y in the second CALL statement; therefore, the order of the actual arguments does not matter.

Another way to invoke or reference a subroutine is with user-defined assignment. A subroutine can define forms of assignment different from the intrinsic assignment supplied by Fortran. Defined assignment is particularly useful with data structures. Defined assignment subroutines require an ASSIGNMENT interface as described in “Argument Keywords”. They have exactly two arguments, arg1 and arg2, both required and the first with intent OUT or INOUT and the second with intent IN. Defined assignment is invoked with the following assignment syntax:

arg1 = arg2

The attributes of the arguments select the defined assignment. This facility, in effect, allows you to extend the generic properties of assignment.

Example of defined assignment:

MODULE POLAR_COORDINATES
    TYPE POLAR
       REAL  ::  RHO, THETA
    END TYPE POLAR
    INTERFACE ASSIGNMENT (=)
       MODULE PROCEDURE ASSIGN_POLAR_TO_COMPLEX
    END INTERFACE
        . . .
    CONTAINS
    SUBROUTINE ASSIGN_POLAR_TO_COMPLEX(C, P)
       COMPLEX, INTENT(OUT)       ::  C
       TYPE(POLAR), INTENT(IN)   ::  P
       C = CMPLX(P%RHO * COS(P%THETA),  &
                 P%RHO * SIN(P%THETA))
    END SUBROUTINE ASSIGN_POLAR_TO_COMPLEX
END MODULE POLAR_COORDINATES

PROGRAM CART
USE POLAR_COORDINATES
COMPLEX :: CARTESIAN
   . . .
CARTESIAN = POLAR(R, PI/6)
   . . .
END PROGRAM

This last assignment is equivalent to the following subroutine call:

CALL ASSIGN_POLAR_TO_COMPLEX(CARTESIAN, POLAR(R, PI/6))

The structure constructor POLAR constructs a value of type POLAR from R and PI/6 and assigns this value to CARTESIAN according to the computations specified in the subroutine.

Functions

A function is similar to a subroutine, except that its principal use is as a primary in an expression. Analogous to a subroutine, a function has an initial FUNCTION statement, a specification part, an execution part, possibly internal procedures, and an END statement. An argument list provides data communication with the function, but in this case arguments typically serve as input data for the function. The principal output is delivered as the function result to the expression invoking the function. Data objects also may be available to the function through host association, use association, and common storage association.

Function Definition

The general format of an external, module, or internal function subprogram is as follows:

[function_prefix]function_statement[ RESULT (result_name) ]
[specification_part]
[execution_part]
[internal_subprogram_part]
END [ FUNCTION [function_name]]

A function is defined as follows:

 

function_subprogram

is

function_stmt
[specification_part]
[execution_part]
[internal_subprogram_part]
end_function_stmt

 

function_stmt

is

[prefix] FUNCTION function_name ([dummy_arg_name_list])
[ RESULT(result_name) ]

 

prefix

is

prefix_spec[prefix_spec] ...

 

prefix_spec

is

type_spec

  

or

RECURSIVE

  

or

PURE

  

or

ELEMENTAL

 

end_function_stmt

is

END [ FUNCTION [function_name]]

The simplest function statement can take the following form:

FUNCTION function_name ([dummy_arg_name_list])

When a function is executed, the dummy arguments become associated with the actual arguments specified in the reference. See “Argument Association”, for more information on argument association.

The following are some example FUNCTION statements:

FUNCTION HOSPITAL(PILLS)
REAL FUNCTION LASER(BEAM)
RECURSIVE CHARACTER*(10) FUNCTION POLICE(STATION) &
       RESULT(ARREST)

The following rules apply to the function prefix:

  • The prefix can contain no more than one of each type of prefix_spec. For example, you cannot specify PURE twice in a prefix.

  • If ELEMENTAL is present, RECURSIVE cannot be present.

  • If you specify ELEMENTAL, you cannot also specify PURE. These specifications are mutually exclusive. If you specify ELEMENTAL or PURE, the function itself must conform to the rules governing elemental or pure procedures. See “Pure Procedures”, for information on pure procedures. See “Elemental Procedures”, for information on elemental procedures.

  • When a function is either directly or indirectly recursive, you must specify RECURSIVE.

The type of the function can be specified in the FUNCTION statement or in a type declaration statement, but not both. If the type is not explicitly specified in this way, the default typing rules apply.

If the function result is array valued or a pointer, the declarations must state these attributes for the function result name. The function result name can be declared to be an explicit-shape or deferred-shape array. If the function is an explicit-shape array, the bounds can be nonconstant specification expressions.

Dummy argument attributes can be specified explicitly in the body of the function or may be declared implicitly. Each dummy argument is a local variable of the function; therefore, its name must be different from that of any other local variable in the function. For more information on this, see “Scope” in Chapter 6.

If the END statement contains the function name, it must be the same name used in the FUNCTION statement.

An internal function must not contain an internal subprogram part.

An internal function must not contain ENTRY statements.

In an internal or module function, the END statement must be of the following form because the keyword FUNCTION is required, as follows:

END FUNCTION [function_name]

If there is no RESULT clause, the function name is used as the result variable. If the function result is scalar and of type integer, real, complex, logical, or character, the function name followed by a left parenthesis is considered to be a recursive reference to the function. Otherwise, it is a reference to the result variable.


Note: The Fortran standard does not specify direct recursion unless a RESULT clause is specified on the FUNCTION statement.

If there is a RESULT clause, the result_name is used as the result variable, and the function name must not be used as the result variable; in this case, all references to the function name are function references (that is, recursive calls).

The function name must not appear in specification statements if there is a RESULT clause.

If the result of a function is not a pointer, its value must be completely defined before the end of execution of the function. If the result is an array, all the elements must be defined; if the result is a structure, all of the components must be defined.

If the result of the function is an array or a pointer to an array, its shape must be determined before the end of execution of the function.

If the result is a pointer, its allocation status must be determined before the end of execution of the function; that is, a target must be associated with the pointer, or the pointer must have been explicitly disassociated from a target.

The INTENT attribute can be specified for the dummy arguments of the function, except that an INTENT attribute must not be specified for a dummy pointer or a dummy procedure.

The PRIVATE and PUBLIC attributes must not be specified in a function.

RESULT Option

As with subroutines, when a function is either directly or indirectly recursive, RECURSIVE must appear in the FUNCTION statement. The RESULT clause specifies a name different from the function name to hold the function result. The result name can be declared, defined, and referenced as an ordinary data object. The function name has the same attributes as the result name. Upon return from a function with a RESULT clause, the value of the function is the last value given to the result name.

If there is no RESULT clause, the function name is used as the result data object. If the function is both array-valued and directly recursive, however, a recursive reference to the function is indistinguishable from a reference to the array-valued result. The RESULT clause resolves this ambiguity by providing one name for the result value (the result name) and another name for recursive calls (the function name).

A simple example of a recursive function is REVERSE, which reverses the words in a given phrase:

RECURSIVE FUNCTION REVERSE(PHRASE) RESULT(FLIPPED)
   CHARACTER(*)           PHRASE
   CHARACTER(LEN(PHRASE)) FLIPPED
   L = LEN_TRIM(PHRASE)
   N = INDEX(PHRASE(1:L), " ", BACK = .TRUE.)
   IF (N == 0) THEN
      FLIPPED = PHRASE
   ELSE
      FLIPPED = PHRASE(N+1:L) // " "  &
            // REVERSE(PHRASE(1:N-1))
   END IF
END FUNCTION REVERSE

Function Reference

One way a function can be referenced or invoked is by placing the function name with its actual arguments as an operand in an expression. The actual arguments are evaluated; argument association takes place in accordance with the rules in “Argument Association”; and the statements in the body of the function are executed. The reference results in a value that is then used as the value of that primary in the expression.

In the following example expression, F is a function of one argument that delivers a numeric result. This result becomes the value of the right-hand operand of the expression:

A + F(B)

A function reference is defined as follows:

 

function_reference

is

function_name ([actual_arg_spec_list])

 

actual_arg_spec

is

[keyword = ]actual_arg

 

keyword

is

dummy_arg_name

 

actual_arg

is

expr

 

 

or

variable

 

 

or

procedure_name

The only difference between subroutine and function argument lists is that a function argument list must not contain an alternate return. Otherwise, the rules and restrictions for actual and dummy arguments are the same for functions and subroutines as those described in “Subroutine Reference”.

A keyword is a dummy argument name in the function interface. As with subroutines, each actual argument is associated with the corresponding dummy argument by position or keyword. A variable is a special case of expression in the context of an actual argument; variables can be associated with dummy arguments used with any intent (IN, OUT, INOUT), whereas other forms of expressions must be associated either with dummy arguments with intent IN or dummy arguments that do not have an INTENT attribute. Note that (A), where A is a variable, is not a simple reference to the variable but is a more general expression.

A reference to an elemental function is an elemental reference if one or more actual arguments are arrays and if all array arguments have the same shape.

The following are examples of function references:

Y = 2.3 * CAPS(4*12.0, K)! FUNCTION CAPS(SIZE, KK)
PRINT *, TIME(TODAYS_DATE)! FUNCTION TIME(DATE)

Another way to reference a function is with user-defined operators in an expression. A number of arithmetic, logical, relational, and character operators are predefined in Fortran; these are called intrinsic operators. These operators can be given additional meanings, and new operators can be defined. Functions define these operations and interface blocks associate them with the desired operator symbols, as described in “Pointer Association”. A function can be invoked by using its associated defined operator in an expression. The rules associated with operator functions are as follows:

  • Functions of one argument are used to define unary operations; functions of two arguments are used to define binary operations.

  • The arguments are required and must have intent IN.

  • New operators must have the dot form, must contain only letters (underscores not allowed) between the dots, must have no more than 31 letters, and must not be the same as logical literal constants such as .TRUE. or .FALSE.. Examples are .FOURIER., .NEWPLUS., and .BLAHANDBLAAH..

If a defined operator is the same as an intrinsic operator (for example, +, *, .EQ., .AND.), it extends the generic properties of this operator, as described. In such an extension, the attributes of the arguments must not match exactly those of the operands associated with an intrinsic meaning of the operator. For more information on intrinsic operations, see the Fortran Language Reference Manual, Volume 1.

In the following example, the presence of .BETA. in the expression in the PRINT statement invokes the function BETA_OP, with X as the first actual argument and Y as the second actual argument. The function value is returned as the value of X .BETA. Y in the expression, as follows:

INTERFACE  OPERATOR (.BETA.)
    FUNCTION BETA_OP(A, B)
        . . . ! attributes of BETA_OP, A, and B
              ! (including INTENT(IN) for A and B)
    END FUNCTION
END INTERFACE
   . . .
PRINT *, X .BETA. Y

Statement Functions

A statement function statement is a function definition that consists of only one Fortran statement.


Note: The Fortran standard has declared the statement function definition statement to be obsolescent.

A statement function statement is defined as follows:

OBS

stmt_function_stmt

is

function_name ([dummy_arg_name_list]) = scalar_expr

A statement function statement can be replaced (except within an internal procedure) with the following equivalent three-line internal function definition:

FUNCTION function_name(dummy_arg_name_list)
function_name = scalar_expression
END FUNCTION

The preceding format assumes that the function and its arguments are typed the same in both cases. Additional rules governing statement functions follow these three examples of statement functions:

Example 1:

CHARACTER(5)  ZIP_5     ! Notice these are scalar
CHARACTER(10) ZIP_CODE  ! character strings
ZIP_5(ZIP_CODE) = ZIP_CODE(1:5)

Example 2:

INTEGER TO_POST, MOVE
TO_POST(MOVE) = MOD(MOVE,10)

Example 3:

REAL FAST_ABS
COMPLEX Z
FAST_ABS(Z) = ABS(REAL(Z)) + ABS(AIMAG(Z))

Note that the function and all the dummy arguments are scalar.

The expression must contain only intrinsic operations and must be scalar valued. Note that this allows the expression to include references to scalar-valued functions having array arguments, such as SUM(A+B), where SUM is the array reduction intrinsic function and A and B are conformable arrays.

Statement functions are defined in the specification part of a program unit, internal procedure, or module procedure. Any other statement function referenced in the expression must have been defined earlier in the specification part, and hence a statement function cannot be recursive (either directly or indirectly).

The primaries of the scalar_expr must be constants (literal or named), references to variables, references to functions and function dummy procedures, or intrinsic operations. If scalar_expr contains a reference to a function or function dummy procedure, the following are true:

  • The reference must not require an explicit interface.

  • The function must not require an explicit interface unless it is an intrinsic.

  • The function must not be a transformational intrinsic.

  • The result must be a scalar.

If an argument to a function or function dummy procedure is array-valued, it must be an array name.

If a reference to a statement function appears in scalar_expr, it must have been defined earlier in the scoping unit, and it cannot be the name of the statement function being defined.

Named constants and variables used in the expression must have been declared earlier in the specification part or made available by use or host association.

If an array element is used in the expression, the parent array must have been declared earlier in the specification part.

The appearance of any entity in the expression that has not previously been typed explicitly constitutes an implicit type declaration and any subsequent explicit type declaration for that entity must be consistent with the implicit type.

Statement function dummy arguments have a scope of the statement function statement.

Statement function dummy arguments are assumed to have the INTENT (IN) attribute (that is, function references in the expression must not change the value of any dummy argument of the statement function).

A statement function must not be used as an actual argument.

A statement function is referenced in the same manner as any other function, except that the statement function interface is implicit and therefore the keyword form of actual arguments is not allowed; the argument association rules are the same.

Note that statement function interfaces are implicit, not explicit; see “Type, Kind, and Rank Matching”, for a discussion of explicit interfaces. Explicit interfaces are associated with those procedures that can have array-valued results, assumed-shape dummy arguments, pointer arguments, and keyword arguments, and can have various generic forms. Because none of these apply to statement functions, statement functions do not have and are not allowed to have explicit interfaces.

Procedure-related Statements

Several procedure-related statements (for example, RETURN, CONTAINS, ENTRY, EXTERNAL, and INTRINSIC) are general in that they apply to both kinds of procedures (functions and subroutines) or to more than one form of procedure (for example, external, internal, module). The following sections describe these statements.

RETURN Statement

A RETURN statement terminates execution of a procedure and returns control to the calling program. Often, however, it is not needed because the procedure END statement performs the same function as well as constituting the physical end of the procedure. It is occasionally convenient to use RETURN statements, however, because they may be placed anywhere in the execution part of the procedure.

The RETURN statement is defined as follows:

 

return_stmt

is

RETURN [scalar_int_expr]

The scalar_int_expr argument is applicable only to subroutines and is used in conjunction with alternate returns. This expression must be of type integer, and its value must be in the range 1 to n, where n is the number of alternate returns in the argument list; the value selects which alternate return, counting from left to right in the argument list, is to be used for this particular return from the procedure. The effect of an alternate return is the same as that produced by the following statements (where inside SUBR, the variable IRET is assigned the integer expression alternate return value prior to returning from SUBR):

CALL SUBR (..., IRET)
GO TO (label_list), IRET

The alternate return is an obsolescent feature.

CONTAINS Statement

The CONTAINS statement separates the internal procedures from the specification and executable parts of the host, and it separates module procedures from the specification part of the module. It is defined as follows:

 

contains_stmt

is

CONTAINS

It is a nonexecutable statement that has the effect of making the execution sequence bypass everything following the CONTAINS statement up to the END statement of the program unit. Therefore, if it were executable, the CONTAINS statement would have the effect of a STOP statement in a main program and a RETURN statement in a procedure subprogram.

The CONTAINS statement serves only to delimit the procedure part of a program unit.

ENTRY Statement

“Procedure Terms”, describes procedure entry. A procedure entry is defined by the appearance of an ENTRY statement in the specification or execution part of the procedure subprogram.

The ENTRY statement is defined as follows:

 

entry_stmt

is

ENTRY entry_name[ ([dummy_arg_list]) ][ RESULT (result_name) ]

The ENTRY statement can be thought of as providing auxiliary FUNCTION statements in function subprograms or SUBROUTINE statements in subroutine subprograms, each defining another procedure. The entry names must be different from one another and from the original function or subroutine name.

The following example illustrates a typical way of using the ENTRY statement to define several procedures in a single subprogram. In this example, the set of executable statements follows each ENTRY statement and precedes the next one. The last one is a RETURN statement, which represents the procedure corresponding to the entry. When the procedure represented by the entry is called, the procedure is entered and execution proceeds from this point. Execution continues in the procedure in the normal manner, ignoring any ENTRY statements subsequently encountered, until a RETURN statement is executed or the end of the procedure is reached.

SUBROUTINE name_1 ( argument_list_1)
      . . .
   RETURN

   ENTRY name_2 (argument_list_2)
      . . .! This falls through past the next ENTRY statement

   ENTRY name_3 (argument_list_3)
      . . .
   RETURN
END

Often the computations in these entry bodies are similar, involving the same data and code.

All of the entries in a subroutine subprogram define subroutine procedures, and all of the entries in a function subprogram define function procedures. All of the entries in a function subprogram must be compatible with storage association. The RESULT option on an ENTRY statement has the same form and meaning as the RESULT option on a FUNCTION statement.

The following are examples of the ENTRY statement:

ENTRY FAST(CAR, TIRES)
ENTRY LYING(X, Y) RESULT(DOWN)

The following list enumerates rules regarding the ENTRY statement:

  1. If an ENTRY statement appears in a function subprogram, the parentheses in the ENTRY statement surrounding the optional dummy argument list must be present.

  2. An ENTRY statement can appear only in an external or module subprogram; an internal subprogram must not contain ENTRY statements.

  3. An ENTRY statement must not appear in an executable construct (IF, DO, CASE, or WHERE constructs) or a nonblock DO loop.

  4. An entry name must not be the same as any dummy argument name in the subprogram.

  5. An entry name must not appear in an EXTERNAL statement, INTRINSIC statement, or procedure interface block in that subprogram.

  6. The RESULT option applies only to function entries and thus may appear only in function subprograms.

  7. If result_name is specified, it must not be the same as any entry name, the function name, or any other result_name. If result_name is specified, the entry_name must not appear in any specification statements in the subprogram; it inherits all of its attributes from result_name.

  8. The keywords PURE, ELEMENTAL, and RECURSIVE cannot be used in an ENTRY statement. Instead the presence or absence of these keywords on the initial SUBROUTINE or FUNCTION statement of the subprogram applies to each entry in the procedure.

  9. If each entry result in a function subprogram has the same type, kind, and shape as the function result, each of the entries identifies (is an alias for) the same result variable. In this case there is no restriction on the nature of the result. For example, the result could be of derived type, either scalar or array, and could have the POINTER attribute.

    If all of the entries in a function subprogram (including the function result) are not the same type, kind, and shape, then they must all be scalar, without the POINTER attribute, and must be capable of being equivalenced. This means they all must be of type character with the same length or any mix of default integer, default real, default logical, double-precision real, or default complex. The reason for these rules is that all subprogram entries are storage associated with the function result.

  10. A dummy argument must not appear in an executable statement before the ENTRY statement specifying that dummy argument. A dummy argument of the ENTRY statement must not appear in a statement function scalar expression before the ENTRY statement specifying that dummy argument, unless it is also a dummy argument of the statement function.

  11. An executable statement or statement function depending on a dummy argument of the procedure that was entered, or upon a local data object depending on that dummy argument (such as a dynamic local array whose size depends on the dummy argument), may be executed only if the dummy argument appears in the ENTRY statement of the referenced procedure. In addition, an associated actual argument must be present if the dummy argument is optional.

For either a function or subroutine subprogram the order, number, types, kind type parameters, and names of the dummy arguments in an ENTRY statement may differ from those in the FUNCTION or SUBROUTINE statement or any other ENTRY statement in that subprogram. Note, however, that all of the entry result values of a function subprogram must be able to be equivalenced to the function result value, as described previously in item 9.

The interface to a procedure defined by an ENTRY statement in an external subprogram can be made explicit in another scoping unit (the calling scoping unit) by supplying an interface body for it in a procedure interface block. In this case the ENTRY statement appears as the first statement of the interface body, but the word ENTRY is replaced by the word FUNCTION or SUBROUTINE, whichever is appropriate. Such an interface body must include RECURSIVE if the subprogram is recursive and must correctly specify the dummy argument attributes and the attributes of the result if it is a function. Entry procedures defined in module procedures already have explicit interfaces in program units that use the module.

EXTERNAL Statement

Consider the following program segment in a program unit that contains no declarations:

   . . .
A = X + Y
CALL B(X, Y)
CALL Q(A, B, C)
   . . .  

It is clear that A is a variable, and B and Q are subroutines. But in this code fragment, C could be either a variable name or a procedure name. The other statements in the program may or may not resolve the mystery. In the cases where they do not, the argument is assumed to be a variable. But when the programmer wants it to be a procedure name, there must be some way to specify it. The means for doing this is the EXTERNAL statement, which is defined as follows:

 

external_stmt

is

EXTERNAL [ :: ]external_name_list

The EXTERNAL statement appears in the program unit in which the procedure in question is an actual argument; the procedure must be an external procedure or dummy procedure. Internal procedures, statement functions, and generic names must not appear as actual arguments. Use association takes care of module procedures, and intrinsic procedures are handled separately. An interface block for the external procedure has the same effect (as well as providing argument checking and other benefits) and, therefore, effectively replaces the EXTERNAL statement for this purpose.

A name that appears in an EXTERNAL statement must not also appear as a specific procedure name in an interface block in the same scoping unit. Another minor use of the EXTERNAL statement is to identify the relevant block data program unit by specifying the block data name on the EXTERNAL statement.

INTRINSIC Statement

The INTRINSIC statement does for intrinsic procedures what the EXTERNAL statement does for external procedures (see the preceding section). The INTRINSIC statement is defined as follows:

 

intrinsic_stmt

is

INTRINSIC [ :: ]intrinsic_procedure_name_list

Note that an interface block cannot be provided for an intrinsic procedure because that would specify a duplicate explicit interface. If the generic intrinsic procedure is being extended with user-supplied subprograms, however, an interface block can have a generic name that is the same as a generic intrinsic procedure name. In a scoping unit, a name can appear both as the name of a generic intrinsic procedure in an INTRINSIC statement and as the name of a generic procedure provided that the procedures in the interface and the specific intrinsic procedures are all functions or are all subroutines.

For example, in the following procedure reference, if the intrinsic function SIN is intended for the third actual argument, SIN must be declared in an INTRINSIC statement if it is not otherwise known to be a procedure name in that scope. (SIN is both a specific and a generic procedure name. It is the specific name that is involved here.)

CALL Q(A, B, SIN)

Pure Procedures

A pure procedure is one that is free from side effects. Such a procedure does not modify data that is visible outside of the procedure. The procedure does not alter global variables or variables accessible by host or use association. It does not perform I/O, and it does not save any variables. It is safe to reference a pure procedure in parallel processing situations and when there is no explicit order of evaluation.

The NOSIDEEFFECTS directive has a functionality that approaches the functionality of the PURE keyword. You can compare the information in this section to the information on the NOSIDEEFFECTS directive in the CF90 Commands and Directives Reference Manual, and the MIPSpro 7 Fortran 90 Commands and Directives Reference Manual.


Note: The Fortran standard does not describe the NOSIDEFFECTS directive.

A pure procedure can be any of the following types of procedures:

  • A pure intrinsic function or subroutine

  • An object defined by a pure subprogram

  • A pure user-defined function or subroutine

A user-defined pure subprogram must have the PURE keyword on the SUBROUTINE or FUNCTION statement.

Several rules govern pure subprograms. Basically, a pure subprogram cannot contain any operation that could conceivably result in an assignment or pointer assignment to a common variable or a variable accessed by use or host association. Nor can a pure subprogram contain any operation that could conceivably perform any external file I/O or a STOP operation.

The word conceivably is used in the preceding paragraph to indicate that it is not sufficient for a pure subprogram merely to be side-effect free in practice. For example, a function that contains an assignment to a global variable in a block that is not executed in any invocation of the function is, nevertheless, not a pure function. Functions like this are excluded to facilitate compile-time checks.

Rules for Pure Procedures

For a function to be pure, most dummy arguments must be specified with the INTENT(IN)attribute in the specification_part. The exception to this is that procedure dummy arguments and dummy arguments with the POINTER attribute cannot be declared as such.

For a subroutine to be pure, you must declare the intents of most dummy arguments in the specification_part. Dummy arguments for which you do not need to specify the intent are procedure arguments, alternate return indicators, and arguments with the POINTER attribute. The constraints for pure subroutines are similar to the constrains on pure functions, but side effects to INTENT(OUT), INTENT(INOUT), and pointer dummy arguments are permitted.

The following additional rules apply to subroutines or functions that you declare to be pure:

  • A local variable declared in the specification_part or internal_subprogram_part of a pure subprogram cannot have the SAVE attribute. Note that when a variable is initialized in a type_declaration_stmt or a DATA statement, the SAVE attribute is implied, so initialization in this manner is also disallowed.

  • You must declare all dummy arguments that are procedure dummy arguments to be PURE in the specification_part of a pure subprogram.

  • If a procedure that is neither an intrinsic procedure nor a statement function is used in a context that requires it to be pure, then its interface must be explicit in the scope of that use. The interface must specify that the procedure is PURE.

  • All internal subprograms in a pure subprogram must be pure.

  • Any procedure referenced in a pure subprogram, including one referenced by a defined operation or assignment, must be pure.

  • Pure subprograms cannot contain a PRINT, OPEN, CLOSE, BACKSPACE, ENDFILE, REWIND, or INQUIRE statement.

  • Pure subprograms cannot contain READ or WRITE (including PRINT) statements that specify an external file unit nor can they contain * as an I/O unit.

  • Pure subprograms cannot contain a STOP or a PAUSE statement.

Using Variables in Pure Procedures

Certain rules apply to variables used in pure subprograms. These rules apply to the following types of variables:

  • Variables in common blocks

  • Variables accessed by host or use association

  • Variables that are dummy arguments to a pure function

  • Variables that are dummy arguments with INTENT(IN) to a pure subroutine

The following rules apply to both the types of variables described in the preceding list and to objects that are storage associated with any such variable. Specifically, these variables and objects cannot be used in the following contexts:

  • As the variable of an assignment statement

  • As a DO variable or implied-DO variable

  • As an input_item in a READ statement from an internal file

  • As an internal_file_unit in a WRITE statement

  • As an IOSTAT= specifier in an input or output statement with an internal file

  • As the pointer_object of a pointer assignment statement

  • As the target of a pointer assignment statement

  • As the expr of an assignment statement in which the variable is of a derived type if the derived type has a pointer component at any level of component selection

  • As an allocate_object or stat_variable in an ALLOCATE or DEALLOCATE statement

  • As a pointer_object in a NULLIFY statement

  • As an actual argument associated with a dummy argument with INTENT(OUT) or INTENT(INOUT) or with the POINTER attribute.

Elemental Procedures

An elemental procedure is an elemental intrinsic procedure or a procedure that is defined by a user-specified elemental subprogram. A user-defined elemental subprogram must have the ELEMENTAL keyword on the SUBROUTINE or FUNCTION statement.


Note: An elemental subprogram is a pure subprogram, and all of the constraints for pure subprograms also apply to elemental subprograms. See “Pure Procedures”, for more information on pure subprograms.

An elemental subprogram is, by definition, also a pure subprogram, but the PURE keyword need not be present. The following additional rules apply to elemental subroutines and functions:

  • All dummy arguments must be scalar and cannot have the POINTER attribute.

  • A function must return a scalar result, and the result cannot have the POINTER attribute.

  • A dummy argument, or a subobject of a dummy argument, cannot appear in a specification_expr except as an argument to the BIT_SIZE(3i), KIND(3i), or LEN(3i) intrinsic functions, or to one of the numeric inquiry functions.

  • A dummy argument cannot be an asterisk (*).

  • A dummy argument cannot be a dummy procedure.

Example:

ELEMENTAL REAL FUNCTION F(A)
  REAL, INTENT(IN) :: A
  REAL(SELECTED_REAL_KIND(PRECISION(A)*2)) :: WORK
  ...
END FUNCTION F    

Elemental Functions

If a generic name or a specific name is used to reference an elemental function, the shape of the result is the same as the shape of the actual argument with the greatest rank. If the actual arguments are all scalar, the result is scalar. For those elemental functions that have more than one argument, all actual arguments must be conformable. In the array-valued case, the values of the elements, if any, of the result are the same as would have been obtained if the scalar-valued function had been applied separately, in any order, to corresponding elements of each array actual argument.

The following is an example of an elemental reference to the MAX(3i) intrinsic function. Assume that X and Y are arrays of shape (M,N). The reference is as follows:

MAX(X, 0.0, Y)

The preceding statement is an array expression of shape (M,N) whose elements have the following values:

MAX (X(I, J),  0.0, Y(I, J))

In the preceding example, I has the values 1 to M, and J has the values 1 to N.

Elemental Subroutines

An elemental subroutine is one that has only scalar dummy arguments, but it may have array actual arguments. In a reference to an elemental subroutine, one of the following situations must exist:

  • All actual arguments must be scalar.

  • All actual arguments associated with INTENT(OUT) and INTENT(INOUT) dummy arguments must be arrays of the same shape and the remaining actual arguments must be conformable with them. In this case, the values of the elements, if any, of the results are the same as would be obtained if the subroutine had been applied separately, in any order, to corresponding elements of each array actual argument.

In a reference to the intrinsic subroutine MVBITS(3i), the actual arguments corresponding to the TO and FROM dummy arguments may be the same variable. Apart from this, the actual arguments in a reference to an elemental subroutine must satisfy the restrictions of “Miscellaneous Argument Association Rules”.

Argument Association

When a procedure is referenced, the actual arguments supply the input data to be used for this execution of the procedure and specify the variables to receive any output data. Within the procedure, the dummy arguments assume the roles of these input and output data objects. Thus, during execution of a procedure reference, the appropriate linkage must be established between the actual arguments specified in the call and the dummy arguments defined within the procedure. This linkage is called argument association.

As shown in Figure 4-1, the fundamental form that a set of actual arguments takes in a reference is that of a sequence of expressions separated by commas. The set of names in a procedure definition after the procedure name is a list of dummy argument names. In each case this is called an argument list (an actual argument list in the former case and a dummy argument list in the latter case). The arguments are counted from left to right.

In Figure 4-1, the actual arguments are shown as solid boxes because these represent, or identify, actual data values or locations. The dummy arguments are shown as dotted boxes to indicate that they do not represent actual data.

Figure 4-1. Actual and dummy argument lists

Actual and dummy argument lists

The principal argument association mechanism is positional; that is, arguments are associated according to their positions in the respective actual and dummy argument lists. The first dummy argument becomes associated with the first actual argument, the second dummy argument becomes associated with the second actual argument, and so on. The remainder of this chapter describes the rules governing this association mechanism and the forms it can take.

Type, Kind, and Rank Matching

An actual argument, being a data object, has the usual set of data object attributes. These can be determined by the specification part of the calling program or, if the actual argument is an expression, by the rules governing expression results. The most important of these attributes, for argument association purposes, are the data type, kind type parameter, and rank of an object. This trio of attributes are referred to as the TKR pattern of the object. Thus, each actual argument, except for alternate returns and procedures as arguments, has a type, kind, rank (TKR) pattern.

Example 1: Suppose, for example, that an actual argument, ERER, has been specified by the following statement:

REAL ERER(100)

The TKR pattern of ERER is real, default kind, rank 1.

Example 2: Assume the following statement:

INTEGER(KIND=SELECTED_INT_KIND(1))(100, 100) IRIR

The TKR pattern of IRIR is integer, nondefault kind, rank 2.

Each dummy argument has a set of attributes just like any other data object, and this set includes a TKR pattern. The dummy argument attributes are specified, either explicitly or implicitly, in the procedure definition.

The most fundamental rule of argument association is that the TKR patterns of an actual argument and its associated dummy argument must be the same. Note that statement function references conform to these rules, except that dummy argument attributes are defined in the host.

The set of dummy arguments can be thought of as the procedure socket; that is, the means by which the procedure gets connected to the rest of the program. Each dummy argument is one of the holes in this socket. One can think of the TKR pattern of a dummy argument as determining the shape of that hole in the socket.

Similarly, the set of actual arguments in a reference to that procedure may be thought of as a plug that connects with the procedure socket (Figure 4-2), with each actual argument representing one prong of the plug. The TKR pattern of an actual argument determines the shape of that prong. For the connection to work properly, the shape of each plug prong must match the shape of the corresponding socket hole.

Figure 4-2. The plug and socket analogy for actual and dummy arguments

The plug and socket analogy for actual and dummy arguments

External procedures and their calling programs are usually compiled separately, so typically, there is no detection of TKR mismatches at compile time. Therefore, TKR argument matching is extremely prone to error, and such mismatches are among the most common and elusive errors in Fortran applications. Explicit procedure interfaces (see “Explicit Interfaces”) solve this problem by enabling automatic detection of TKR argument mismatches.

Associated actual and dummy arguments must have the same data type, the same kind parameter for that type, and the same rank. This last part means that if one is a scalar, they both must be scalars; otherwise, they must both be arrays with the same number of dimensions. (See “Sequence Association”, for an exception to this general rule on rank matching.) Alternate returns are a special case, as are procedures used as arguments.

Argument associations involving arrays and pointers also have some special considerations; they are treated in “Sequence Association”, and “Pointer Association”, respectively. Scalar data objects without the POINTER attribute are discussed here. The rule is simple: the associated dummy argument for a scalar actual argument must be scalar and must have the same data type and kind type parameter value as the actual argument. The exception to this is explained in “Pointer Association”, in which an array element (which is a scalar) may be passed to a dummy array. Note that array elements, scalar-valued structure components, and substrings are valid scalar actual arguments. The only slightly complicated case involves arguments of type character because scalar character objects have an additional attribute: the character length.

The cleanest situation is when the associated actual and dummy argument character lengths are the same. This can be achieved by explicitly declaring the character length in each case, with the length value specified to be the same. In many cases this is an impossibly severe condition, however, because it prevents the development of general-purpose procedures (for example, procedures that can accept character input of any length). Assumed length dummy arguments alleviate this problem.

Assumed length can be specified only for dummy argument data objects. This is done by specifying an asterisk (*) for the character length. An assumed-length dummy argument does not have a length until it becomes associated with an actual argument. When it becomes associated, its length becomes the length of the actual argument. In effect, the length of the actual argument is passed as part of the actual argument and is picked up by the dummy argument in the course of argument association.

Explicit declared length is permitted for dummy arguments, however, so there must be rules governing those instances when the lengths of the actual argument and its associated dummy argument are different. For scalars, the rule is straightforward: the lengths of associated actual and dummy character arguments may be different only if the actual argument length is greater than the dummy argument length.

For arrays, the rules are somewhat complicated and are described in detail in “Array Element Sequence Association”.

Sequence Association

For array arguments, the fundamental rule in Fortran is that the shapes of an actual argument and its associated dummy argument must be the same. That is, they must have the same rank and the same extent (number of elements) in each dimension; thus, they also are the same size. To make this simple rule viable and to make passing array sections viable, you can use an assumed-shape dummy argument. Assumed-shape dummy arguments for arrays are analogous to assumed-length dummy arguments for character arguments in that assumed-shape dummy arguments assume their shape attributes from the actual argument upon association. If you use assumed-shape dummy arguments, you must ensure that the ranks of the actual and dummy arguments agree as well as the type and kind; the rest follows automatically, and association is on an element-by-corresponding-element basis. Thus, again, TKR is the only rule to observe when using assumed-shape dummy arguments. Assumed-shape dummy arguments are declared as described in “Array Element Sequence Association”.

An array is considered an object in and of itself, as well as a sequence of related but separate elements. Array argument association mechanisms are geared towards associating array element sequences rather than associating array objects. These mechanisms are considerably more complicated than the simple TKR pattern matches, although they do offer somewhat more functionality.

An analogous need for object association for structures arises as well. The need arises in order to accommodate the development of external programs that use structure arguments but do not have access to a module defining the type of the structure. As with arrays, the method of association is sequence association that relies on a form of storage layout, like storage association. For more information on structure sequence association, see “Structure Sequence Association”.

Array Element Sequence Association

If a dummy argument is declared as an explicit-shape array or an assumed-size array, then the ranks of the actual argument and its associated dummy argument do not have to be the same, although the types and kinds still have to match. In this case the actual argument is viewed as defining a sequence of objects, each an element of the actual array. The order of these objects is the array element order of the actual array. (Array element order is a linear sequence of the array elements obtained by varying the first subscript most rapidly through its range, then the second subscript, and so on.) The number of objects in this sequence is the size of the actual array.

Similarly, the dummy array is viewed as defining a linear sequence of dummy array elements, in array element order of the dummy array. The association of the dummy array and actual array is the association of corresponding elements in these sequences. To determine associated elements, the two sequences are superimposed with the initial elements of each corresponding with each other. This is illustrated in Figure 4-3, in which a three-dimensional actual array is associated with a two-dimensional dummy array. In this example, this causes the actual argument element AA(1,2,2) to become associated with dummy argument element DA(4,2), for example. The only additional rule that needs to be observed is that the size of the dummy array cannot exceed the size of the actual array. An assumed-size dummy array extends to and cuts off at the end of the actual argument array sequence.

Figure 4-3. Example of array element sequence association

Example of array element sequence association

For character arrays, character length is again an issue, because the array element length must be specified in this case. The lengths of the actual and dummy array elements can be different. Here, the actual and dummy arguments are viewed as sequences of characters. Each array element, in array element order, contributes a subsequence of characters the size of its length to the corresponding sequence of characters representing the argument. The argument association is then on a character-by-corresponding-character basis of these two character sequences. This can result in array element boundary crossing between the actual and dummy arguments, as illustrated in Figure 4-4. In this case, the size rule is that the number of characters in the dummy array cannot exceed the number of characters in the actual array. Using the example in Figure 4-4, these rules cause the dummy argument element DA(4) to be associated with the last character of the actual argument element AA(2,1) and the first two characters of actual argument element AA(1,2).

Figure 4-4. Array element sequence association for default characters

Array element sequence association for default characters

The provision that the ranks of the actual and dummy argument arrays need not match in array element sequence association has an interesting asymmetrical end condition when one is a scalar (effectively a rank of zero). The case of the actual argument having nonzero rank and the dummy argument being scalar occurs for elemental references to intrinsic functions. The reverse, passing a scalar to a dummy array, is allowed in a limited way in array element sequence association. If the dummy argument meets the conditions for array element sequence association (that is, it is declared as an explicit-shape or assumed-size array), the actual argument can be a single array element but cannot be any other kind of scalar.

In the array element sequence association paradigm, the appearance of an array element as the actual argument causes the sequence of actual array elements to begin with this element, rather than the first element of the array, and extend to the end of the array in array element order. This sequence is then associated with the full dummy argument sequence. Care must be taken to ensure that the size of the dummy array is not greater than the size of the array element sequence from the specified array element on. An element of an assumed-shape or pointer array cannot be passed to a dummy array.

An actual argument of type character can be a substring of an array element. The reason is that for character arguments, the array sequence is character based rather than array-element based. The substring provides a third way (together with an array and an array element) to specify the beginning of the actual argument character sequence. As with the other two, the sequence extends to the end of the actual array in array element order. Also, as with the other two, the number of characters in the associated dummy array must not exceed the number in the specified portion of the actual array. In addition, as in the array element case, the substring must not be from an element of an assumed-shape or pointer array.

Passing Array Sections

The passing of array sections in procedure references represents an important part of the array processing facility. Assumed-shape dummy arguments provide the normal method of passing array sections.

There are three principal ways of forming an array section:

  1. An array reference containing a subscript triplet

  2. An array reference containing a vector subscript

  3. A structure component reference in which a part other than the rightmost is array valued

An array section can also be passed to an explicit-shape or assumed-size dummy array. The array arguments of procedures with implicit interfaces are assumed to be sequence associated with the dummy arguments. In this case the section must be converted (copied) to a form acceptable for array element sequence association, and possibly reconverted upon return (for example, if it returns results from the procedure execution). Such conversion results in performance inferior to that obtained from using assumed-shape dummy arguments and is the price of passing array sections to explicit-shape or assumed-size arrays. (Note that assumed-shape dummy arguments require explicit interfaces.)

To summarize, in the case of assumed-shape dummy arguments, the TKR association rules apply. Otherwise the array element sequence association rules apply to the compacted section. One restriction that applies to the use of array sections as actual arguments, regardless of the nature of the dummy argument, is that array sections generated by vector subscripts are not definable; they must not be assigned new values by the procedure. The associated dummy argument must not have the INTENT(OUT) or the INTENT(INOUT) attribute, or be treated as if they did have either of these attributes. The reason is that with vector subscripts the same actual array element could be part of the array section more than once, and thereby this actual array element becomes associated with more than one dummy argument element. If such an object could be defined, conflicting values could be specified for the same actual array element.

Miscellaneous Argument Association Rules

The following paragraphs contain some miscellaneous rules regarding argument association.

If the dummy argument is assumed shape, the actual argument must not be an assumed-size array. An assumed-shape dummy argument requires that complete shape information about the actual argument be supplied to the dummy argument. Because the size of an assumed-size array is open ended, complete shape information is not available for the assumed-size array. Note that a section of an assumed-size array can be used as an actual argument, provided such a section is not open ended (that is, the extent of the last dimension is explicitly specified).

The same data object coming into a procedure through two or more arguments must not be defined. For example, if A(1:5) is an actual argument and A(3:9) is another actual argument, then the three elements A(3:5) have come in through two arguments. In this case none of the three elements A(3:5) can be defined in the procedure. This restriction need not involve arrays, and applies to any data object associated to two dummy arguments. If A in the above example were a character string, the same associations are possible and the same restrictions apply. Even for a simple scalar this can be the case. If K is a scalar integer variable, it may appear twice in the actual argument list, but if it does, it must not become defined as a result of a reference to the procedure.

A data object can be available to a procedure through argument association and by a different method of association. For example, it might come in as an actual argument and also be available through use or host association. In this case it can be defined and referenced only as a dummy argument. It would be illegal to assign A a value within subroutine S in the following example:

CALL S(A). . .
CONTAINS
   SUBROUTINE S(D)
      D = 5
   . . .  

If the dummy argument is an array that has the POINTER attribute, it is effectively an assumed-shape dummy argument. Therefore the TKR rules apply to associated actual arguments. (The argument association rules that apply to pointers is the topic of the next section).

For generic references, defined operators, or defined assignments in which the procedure is not elemental, the TKR method is required for all arguments and operands. Thus, an array element must not be passed to an array dummy argument under any circumstance. For example, if SQUIRT is a generic procedure name, then SQUIRT(A(7)) has a scalar actual argument and the associated dummy argument must be scalar. If the generic procedure allows both a scalar dummy argument and an array dummy argument, the specific procedure with the scalar dummy argument is selected.

An array is never passed to an intrinsic procedure if the actual argument is an array element; only the array element is passed.

Structure Sequence Association

If a structure is a dummy argument of an external procedure, the derived type for the structure must be specified so that it is exactly the same type as that for the corresponding actual argument. The preferred way to do this is to define a derived type in a module and access the module through a USE statement, both for the external procedure and for the program unit referencing it. An alternative way is to use structure sequence association. This technique avoids the need for a module but bypasses the error checking available in the compiler.

Two structures are structure sequence associated if one is an actual argument and the other is the corresponding dummy argument, and the types of the two structures are equivalent but not the same. Two derived types are equivalent if the two types have the same name, are sequence types, have no components that are private or are of a private type, and have components that agree in order, name, and attributes. Having the same attributes means having the same or equivalent type.

When a reference to a procedure is made using structure sequence association, the calling and called program units can assume a consistent storage layout that causes the structures to be associated correctly. This allows values to be passed into and out of the procedure from the calling program.

Pointer Association

Generally, a data object may have the POINTER attribute, the TARGET attribute, or neither of these attributes, but not both. (A structure component that has the POINTER attribute can effectively also have the TARGET attribute if the structure has the TARGET attribute.) A dummy argument can be any of these three, as may an actual argument, but of the nine possible combinations for associated actual and dummy arguments, two are disallowed and of the remaining cases, only the five labeled A through E in Figure 4-5, are distinct (the other two are equivalent to the cases below them in the figure). AESA is an acronym for Array Element Sequence Association.

Figure 4-5. Association of objects with POINTER and TARGET attributes

Association of objects with  POINTER and  TARGET attributes

In combination E in Figure 4-5, neither the actual or dummy argument has either the POINTER or TARGET attribute; this situation is explained in the previous two sections. Combinations B, C, and D are similar; they are the cases in which either the actual or dummy argument, or both, have the TARGET attribute. As far as argument association is concerned, these cases are very much like combination E; that is, either TKR or AESA applies.

Because cases B, C, and D in Figure 4-5 involve arguments with the TARGET attribute, there may be pointers associated with these targets. In the calling program, a target object can be used as an actual argument (cases B and C), and at the time of the call there may be pointers associated with this target. In the procedure, a dummy argument can have the TARGET attribute (combinations B and D), which means that during execution of the procedure a pointer, including another dummy argument with the POINTER attribute, may become associated with this TARGET argument.

The rules governing the associated pointers of target arguments are as follows:

  1. If the dummy argument does not have the TARGET or POINTER attribute, any pointers associated with the actual argument do not become associated with the corresponding dummy argument on invocation of the procedure. If such a dummy argument is associated with a dummy argument with the TARGET attribute, whether any pointers associated with the original actual argument become associated with the dummy argument is processor dependent.

  2. If the dummy argument has the TARGET attribute and is either scalar or an assumed-shape array, and the corresponding actual argument has the TARGET attribute but is not an array section with a vector subscript, then the following conditions exist:

    • Any pointers associated with the actual argument become associated with the corresponding dummy argument on invocation of the procedure.

    • When execution of the procedure completes, any pointers associated with the dummy argument remain associated with the actual argument.

    In the following example, the actual argument is a target and no vector-valued subscripts are passed:

    REAL, POINTER     :: PBEST
    REAL, TARGET      :: B (10000)
    CALL BEST (PBEST, B)         ! UPON RETURN, PBEST IS
    ...                          ! ASSOCIATED WITH THE
    ...                          ! 'BEST' ELEMENT OF B
    ...
    CONTAINS
      SUBROUTINE BEST (P, A)
        REAL, POINTER :: P
        REAL, TARGET  :: A (:)
          ...                    ! FIND THE 'BEST' ELEMENT A(I)
        P=> A (I)
      RETURN
      END SUBROUTINE BEST
    END

  3. If the dummy argument has the TARGET attribute and is an explicit-shape array or is an assumed-size array, and the corresponding actual argument has the TARGET attribute but is not an array section with a vector subscript, then the following conditions exist:

    • On invocation of the procedure, whether any pointers associated with the actual argument become associated with the corresponding dummy argument is processor dependent.

    • When execution of the procedure completes, the pointer association status of any pointer that is pointer associated with the dummy argument is processor dependent.

    The previous two bullets indicate that a valid implementation can choose to pass the address of a copy of the actual argument rather than the address of the actual argument.

  4. If the dummy argument has the TARGET attribute and the corresponding actual argument does not have the TARGET attribute or is an array section with a vector subscript, any pointers associated with the dummy argument become undefined when execution of the procedure completes.

Case A in Figure 4-5, illustrates that both the actual argument and the dummy argument can have the POINTER attribute. When the dummy argument is a pointer, the procedure interface must be explicit in the calling program (see “Explicit Interfaces”), and the associated actual argument must also be a pointer. In this case the following rules apply:

  1. The TKR association rules apply.

  2. Upon argument association, the dummy argument acquires the same pointer association status as the actual argument and becomes pointer associated with the same target as is the actual argument, if the actual argument is associated with a target.

  3. During procedure execution, the pointer association status of the dummy argument can change, and any such changes are reflected in the actual argument.

Cases F and G in Figure 4-5, are those in which the actual argument is a pointer but the dummy argument is not. In this case, the actual argument must be associated with a target, and it is this target that becomes argument associated with the dummy argument. Thus, these two cases are equivalent to cases B and C. In effect, the appearance of a pointer as an actual argument, without the dummy argument known to be a pointer, is treated as a pointer reference (a reference to the target). For example, calling programs can pass target-associated pointers to procedures, because in reality, the underlying (pointed to) object is passed.

The two cases in Figure 4-5, described as not allowed are illegal because the actual arguments would be incompatible with (pointer) operations allowable on the dummy argument.

In case C the procedure interface need not be explicit in the calling program. In cases A, B, and D, an explicit interface is required.

Argument Keywords

The fundamental pairing of arguments in the actual argument list with those in the dummy argument list is positional, as shown in Figure 4-1, but Fortran also provides an order-independent way of constructing actual argument lists. With this option the programmer can explicitly specify in the call which actual argument is to be associated with a dummy argument rather than using its position in the actual argument list to determine the pairing. To do this, the name of the dummy argument, which in this context is referred to as a keyword, is specified in the actual argument list along with the actual argument. It takes the following form:

dummy_argument_name = actual_argument

This form can be used for all of the actual arguments in an actual argument list, and the arguments can be in any order. A reference can use keywords for only some of the actual arguments. For those actual arguments not having keywords, the positional mechanism is used to determine the associated dummy arguments. Positionally associated actual arguments must appear in the actual argument list before the keyword actual arguments. After the appearance of the first keyword actual argument (if any) in the actual argument list, all subsequent actual arguments must use keywords. This is shown in the following examples:

CALL GO(X, HT=40)
CALL TELL(XYLOPHONE, NET=10, QP=PI/6)

Thus, when only some arguments in the actual argument list use keywords, the first part is positional, with no argument keywords, and the last part uses keywords. In the keyword portion of the list the order of the arguments is completely immaterial, and the keyword alone is used to determine which dummy argument is associated with a given actual argument. Care must be taken with keyword arguments in each call to make sure that one and only one actual argument is specified for each required dummy argument and that at most one actual argument is specified for each dummy argument.

Keyword actual argument lists can aid readability by decreasing the need to remember the precise sequence of dummy arguments in dummy argument lists. This functionality, and the form that it takes, is modeled after keyword specifiers in I/O statements. The one situation that requires keyword arguments is when an optional argument not at the end of the argument list is omitted; keyword arguments constitute the only way to skip such arguments in an actual argument list.

To use keyword actual arguments, the procedure interface must be explicit in the scope of the program containing the reference. The compiler can generate the proper reference in this case because the defined sequence of dummy argument names (keywords) is known to the calling program. Intrinsic, internal, and module procedure interfaces are always explicit, so keyword references can be used with these. An interface block must be provided in the calling program for an external procedure before keyword references can be made to it. The price of an interface block comes with an interesting benefit not available from the automatic explicitness of intrinsic, internal, and module procedure interfaces -- the keywords do not have to be the same as the dummy argument names in the procedure definition. This ability to tailor the argument keywords to the application is available only with external procedures.

Optional Arguments

Fortran includes the ability to specify that an argument be optional. An actual argument need not be supplied for a corresponding optional dummy argument in a particular reference, even though it is in the list of dummy arguments. In this case, an optional argument is specified by giving the dummy argument the OPTIONAL attribute, either in an entity-oriented declaration that includes the OPTIONAL attribute or by its inclusion in an OPTIONAL statement in the procedure definition. The OPTIONAL attribute can be specified only for a dummy argument. Any dummy argument in any procedure can be specified to be optional.

In a positional argument list, an optional argument at the right-hand end of the list can be simply omitted from the reference. To omit an argument from the keyword part of an actual argument list, that dummy argument name is not used as one of the keywords. Note that the keyword technique must be used to omit an optional argument that is not at the end of the list, unless all of the remaining arguments are also being omitted in this reference. This is shown in the following example:

CALL TELL(1.3, T=F(K))
   . . .
SUBROUTINE TELL (X, N, T)
   OPTIONAL N, T
      . . .
END

Optional arguments require explicit procedure interfaces.

During execution of a procedure with an optional dummy argument, it is usually necessary to know in that particular reference if an actual argument has been supplied for that dummy argument. The PRESENT intrinsic function is available for that purpose. It is an inquiry function and has one argument, the name of an optional argument in the procedure. Upon execution it returns a value of default logical type, depending on whether or not the dummy argument is associated with an actual argument.

IF (PRESENT(NUM_CHAR)) THEN
  ! Processing if an actual argument has been
  ! supplied for optional dummy argument NUM_CHAR
   USABLE_NUM_CHAR = NUM_CHAR
ELSE
  ! Processing if nothing is supplied for NUM_CHAR
   USABLE_NUM_CHAR = DEFAULT_NUM_CHAR
END IF

The preceding example illustrates how you can use the PRESENT function to control the processing in the procedure as is appropriate depending on the presence or absence of an optional argument. For an optional dummy argument not present (corresponding actual argument not supplied), the following rules apply:

  • A dummy argument not present must not be referenced or defined. If it is a type for which default initialization is specified for some component, the initialization has no effect.

  • A dummy procedure not present must not be invoked.

  • A dummy argument not present must not be supplied as an actual argument corresponding to a nonoptional dummy argument, except in a reference to the PRESENT intrinsic function.

  • A dummy argument not present may be supplied as an actual argument corresponding to an optional dummy argument. In this case, the latter dummy argument is also considered to be not present.

  • If it is an array, it must not be supplied as an actual argument to an elemental procedure unless an array of the same rank is supplied as an actual argument corresponding to a nonoptional dummy argument of that elemental procedure.

  • If it is a pointer, it must not be supplied as an actual argument corresponding to a nonpointer dummy argument other than as the argument to the PRESENT(3i) intrinsic function.

Argument Intent

Any dummy argument, except a procedure or pointer, can be given an INTENT attribute (see the Fortran Language Reference Manual, Volume 1). There are three possible formats for this attribute:

INTENT(IN)
INTENT(OUT)
INTENT(INOUT)

The INTENT attribute can be specified only for dummy arguments and indicates something about the intended use of the argument in the procedure. The use of this attribute enables the compiler to detect uses of the argument within the procedure that are inconsistent with the intent.

INTENT(IN) specifies that an argument is to be used to input data to the procedure, is therefore defined upon entry to the procedure, is not to be used to return results to the calling program, and must not be redefined by the procedure.

INTENT(OUT) specifies that an argument is to be used to return results to the calling program and cannot be used to supply input data. A dummy argument with INTENT(OUT) must not be referenced within the procedure before it is defined unless it is a type for which default initialization is specified. The actual argument associated with an INTENT(OUT) dummy must be a definable data object, that is, a variable.

INTENT(INOUT) specifies that an argument has a defined value upon entry to the procedure and that this value can be redefined during execution of the procedure; it can be referenced before being changed. This would be the intent, for example, of a data object whose value is to be updated by the procedure. The actual argument associated with an INTENT(INOUT) dummy must be a definable data object.

Actual arguments that are array sections with vector-valued subscripts are not allowed to be associated with dummy arguments having INTENT(OUT) or INTENT(INOUT); that is, the associated dummy argument must not be defined.

The use of the INTENT attribute for a dummy argument does not require an explicit interface, because it governs use within the procedure. Making the interface of a procedure containing an INTENT(OUT) or INTENT(INOUT) dummy argument explicit in the calling program, although not required, can nevertheless be useful in detecting possible attempts to use nondefinable data objects for the associated actual argument.

If the INTENT attribute is not specified for a dummy argument, it can be referenced only if the actual argument can be referenced. It can be defined only if the actual argument can be defined.

Resolving References to Generic Procedures

Two or more procedures are generic if they can be referenced with the same name. With such a reference it must be possible to determine which of the procedures is being called. That is, a generic reference must be resolved to that specific procedure in the set of procedures sharing the generic name to which the call applies. The distinguishing property of the reference that is used for this resolution is the nature of the actual argument list. The sequence of TKR patterns in the actual argument in effect selects the appropriate specific procedure to be called.

The set of specific procedures making up the generic set are restricted such that any given sequence of actual argument TKR patterns will match only one of the dummy argument lists of this set. Thus, the requirement of TKR matches in the argument lists can be used to resolve generic references. The operational rules follow; for further details see “Resolving Procedure References” in Chapter 6. Considering the dummy argument lists of any two procedures in the generic set, one of them must have a required dummy argument that satisfies both of the following conditions:

  • It must be in a position in the list at which the other list has no dummy argument or it has a TKR pattern different from that of the dummy argument in the same position in the other list.

  • It must have a name different from all the dummy argument names in the other list or it must have a TKR pattern different from that of the dummy argument with the same name in the other list.

The reason for the second of these rules is the need for unique resolution with respect to references with keyword arguments, as well as strictly positional actual argument lists. “Generic Procedures”, contains an example that illustrates why just the first rule is not enough.

Because resolution of a generic reference requires matching the actual argument list with the candidate dummy argument lists from the generic set, clearly the interfaces of the procedures in the generic set must be explicit in the scoping unit containing the reference. How this is done and how a procedure is added to a generic set is described in “Generic Procedures”.

Elemental References to Intrinsic Procedures

As mentioned previously, in certain special cases involving references to intrinsic procedures, the rule that disallows passing an actual array argument to a scalar dummy argument is relaxed. Many intrinsic procedures have scalar dummy arguments, and many of these can be called with array actual arguments. These are called elemental intrinsic procedures.

Elemental functions are defined to have scalar results as well as scalar dummy arguments. For an elemental intrinsic function with one argument, calling that function with an array argument causes the function to be applied to each element of that array, with each application yielding a corresponding scalar result value. This collection of result values, one for each element of the actual argument, is returned to the calling program as the result of the function call in the form of an array of the same shape as the actual argument. Thus, the function is applied element-by-element (hence the term elemental reference) to the actual argument, resulting in an array of the same shape as the argument and whose element values are the same as if the function had been individually applied to the corresponding elements of the argument.

The square root function SQRT is an example of an elemental intrinsic function. Its dummy argument is a scalar, and it returns a scalar result. The following example shows a typical reference to SQRT:

Y = SQRT(X)

If both X and Y are scalar variables, this would be a normal call to SQRT. Now assume that X and Y are both one-dimensional arrays with bounds X(1:100) and Y(1:100). The previous assignment statement is still valid and has a result equivalent to the following:

DO J = 1, 100
   Y(J) = SQRT(X(J))
END DO

The elemental call to SQRT, however, does not imply the ordering of the individual computations that is specified by the DO construct.

According to the rules of intrinsic assignment, X and Y must have the same shape.

An elemental procedure that has more than one dummy argument can still be called elementally if all of the dummy arguments and the result are scalar and if the actual arguments are conformable. The exception to this, however, is if the name of the dummy argument is KIND (which means its value is a kind type value), its associated actual argument must be scalar. The other actual arguments can be scalars or arrays, as long as they are conformable, and the result has the shape of these arrays or a scalar. The KIND actual argument specifies the kind value for the resulting array.

All of the elemental intrinsic procedures are identified as such in the man pages for each intrinsic procedure. Many have multiple arguments (including the single elemental intrinsic subroutine MVBITS) and many have a KIND dummy argument. In the case of MVBITS there is no function result (one of the arguments returns the result), but the rule for conformable actual arguments is the same as for the elemental functions.

Alternate Returns

An alternate return is one of the two kinds of procedure arguments that are not data objects. The other is a dummy procedure. Alternate returns can appear only in subroutine argument lists. They are used to specify a return different than the normal execution upon completion of the subroutine.

There can be any number of alternate returns in a subroutine argument list, and they can appear at any position in the list. In the dummy argument list each alternate return is simply an asterisk. For example, the following dummy argument list for subroutine CALC_2 has two alternate return indicators, in the second and fifth argument positions:

SUBROUTINE CALC_2(A, *, P, Q, *)

Alternate returns cannot be optional, and the associated actual arguments cannot have keywords.

An actual argument associated with an alternate return dummy argument must be an asterisk followed by a label of a branch target in the scope of the calling program. These actual arguments specify the return points for the corresponding alternate returns. For example, the following is a valid reference to CALC_2:

CALL CALC_2(X, *330, Y, Z, *200)

This assumes that the statements labeled 200 and 330 are branch targets. The statement having the label 330 is the return point for the first alternate return, and the statement having the label 200 is the return point for the second alternate return.

Using an alternate return is done with the extended form of the RETURN statement, which is defined as follows:

RETURN scalar_int_expr

The scalar integer expression must have an integer value between 1 and the number of asterisks in the dummy argument list, inclusive. The integer scalar expression value selects which of the alternate returns, counting from left to right, is to be utilized. Assuming the preceding example call, the following results can be expected:

RETURN  2  ! returns to statement 200 in
           !   the calling program
RETURN (1) ! returns to statement 330
RETURN     ! normal return from the call

Alternate returns are an obsolescent feature.

Dummy Procedures

A dummy argument can be a name that is subsequently used in the procedure as a procedure name. That is, it can appear in an interface block, in an EXTERNAL or INTRINSIC statement, or as the name of the procedure referenced in a function or subroutine reference. The associated actual argument must be the name (without an argument list) of an external, module, intrinsic, or dummy procedure.

The actual argument must not be the name of an internal procedure or a statement function.

The actual argument must not be a generic procedure name, unless there is a specific procedure with the same name; only specific procedures may be passed in argument lists.

If the interface of the dummy procedure is explicit, the associated actual procedure must be consistent with this interface as described in “Explicit Interfaces for External Procedures”. However, a pure or elemental procedure can be associated with a dummy procedure that is not pure or elemental.

If the dummy procedure is typed, referenced as a function, or has an explicit function interface, the actual argument must be a function.

If the dummy procedure is referenced as a subroutine or has an explicit subroutine interface, the actual argument must be a subroutine.

Dummy procedures can be optional, but must not have the INTENT attribute. They can occur in either function or subroutine subprograms. The associated actual argument can be specified by using a keyword.

Procedure Interfaces

The term procedure interface refers to those properties of a procedure that interact with or are of direct concern to a calling program in referencing the procedure. These properties are the names of the procedure and its dummy arguments, the attributes of the procedure (if it is a function), and the attributes and order of the dummy arguments. If these properties are all known to the calling program (that is, known within the scope of the calling program), the procedure interface is said to be explicit in that scope; otherwise, the interface is implicit in that scope.

An interface block can be used in the specification part of a scoping unit to make explicit a procedure interface (other than a statement function) that otherwise would be implicit in that scoping unit. In addition, interface blocks:

  • Allow you to give generic properties to procedures, including extending intrinsic procedures

  • Define new user-defined operators and extend the generic properties of intrinsic operators

  • Extend the assignment operation to new data combinations (user-defined coercions)

  • Specify that a procedure is external

The following sections describe the roles of explicit interfaces, situations in which explicit interfaces are needed, when a procedure definition provides an explicit interface, and all of the uses of interface blocks.

Explicit Interfaces

The following situations require explicit interfaces:

  1. Optional arguments

  2. Array-valued functions

  3. Pointer-valued functions

  4. Character-valued functions whose lengths are determined dynamically

  5. Assumed-shape dummy arguments (needed for efficient passing of array sections)

  6. Dummy arguments with the POINTER or TARGET attribute

  7. Keyword actual arguments (which allow for better argument identification and order independence of the argument list)

  8. Generic procedures (calling different procedures with the same name)

  9. User-defined operators (which is just an alternate form for calling certain functions)

  10. User-defined assignment (which is just an alternate form for calling certain subroutines)

  11. References to pure procedures

Explicit interfaces are required for items 1 and 7 in this list so that the proper association between actual and dummy arguments can be established. Recall that any of the arguments in the dummy argument list can be declared to be optional and any such argument can be omitted in a reference to the procedure. Keyword arguments allow actual arguments to occur in any order and are needed when omitting an optional argument that is not the last in the dummy argument list. Consider, for example, the following procedure:

SUBROUTINE EX (P, Q, R, S, T)
OPTIONAL Q, R, T

The following calls are all valid:

CALL EX(V, W, X, Y, Z)

CALL EX(V, W, X, Y)
                  ! Last argument omitted

CALL EX(P=V, Q=W, R=X, S=Y, T=Z)
                  ! Same as first call

CALL EX(P=V, Q=W, R=X, S=Y)
                  ! Same as second call

CALL EX(P=V, S=Y)
                  ! All optional arguments omitted

CALL EX(S=Y, P=V) ! Same as fifth call

CALL EX(R=X, S=Y, P=V, Q=W)
                  ! Same as second call

CALL EX(S=Y, T=Z, Q=W, P=V)
                  ! An optional argument omitted

The last four of these example CALL statements illustrate why explicit interfaces are needed for optional and keyword arguments. Namely, so that the calling routine knows the names of the dummy arguments in order that the proper subroutine reference can be generated.

Items 2 and 4 in the preceding list involve function results whose size (number of items returned) is determined by the procedure and may be different from reference to reference. Explicit interfaces convey the necessary information to the calling routines to process such references correctly.

In item 3, the calling procedure needs to know that there is a layer of indirection (the pointer) buffering the actual data involved.

Item 5 represents a significant Fortran functionality -- one that requires additional information in the calling program that is provided by an explicit interface. With discontiguous arrays, additional information must be passed in the call. You can pass sections of arrays as arguments, which can comprise array elements discontiguous in storage, and can represent very sparse array sections. Assumed-shape dummy arrays are provided to accommodate this new form of array passing. Any array, contiguous or not, can be passed to either form of dummy argument, assumed-shape or otherwise. For implicit interfaces, an explicit-shape or assumed-size dummy argument is the default, and, therefore, assumed-shape arguments require explicit interfaces. Discontiguous array sections can be passed to explicit-shape or assumed-size dummy arguments, but in this case the CF90 and MIPSpro 7 Fortran 90 compilers pack such sections into contiguous temporaries on entry to the procedure and unpack them on return, incurring performance penalties.

Dummy arguments with the POINTER or TARGET attribute (item 6) require explicit interfaces because an actual argument can be a pointer, but what is passed can be either the pointer itself or the target. Which one is passed depends upon what the procedure expects, and whether or not the dummy argument has the POINTER attribute. The explicit interface provides the required information. The default for implicit interfaces is that the target is passed.

Generic procedures (item 8) must have explicit interfaces because the calling routine must be able to disambiguate a generic procedure name; that is, because generic means two or more procedures with the same name, the calling routine must have enough information to determine which specific procedure to invoke for a given reference. An explicit interface provides this information by making dummy argument attribute information available to the calling routine. The specific procedure called is the one for which the dummy argument attribute pattern matches that for the actual arguments. Generic procedures, including the use of interface blocks for configuring generic names, are discussed in detail in “Generic Procedures”.

User-defined operators (item 9) represent an alternative way to reference certain functions. They allow the use of infix operator notation, rather than traditional function notation for two-argument functions. Thus, for example, A + B can be used in place of RATIONAL_ADD(A, B) if A and B are of the derived type representing rational numbers, and the operator + has been extended as the operator form of RATIONAL_ADD. An example of using a new operator, rather than extending an intrinsic operator, is P .SMOOTH. 3, where P represents a matrix of picture elements to be smoothed and 3 is the size of the smoothing neighborhood. This is alternative syntax for the function reference PICTURE_SMOOTH(P,3). Such alternative syntax provisions are similar to generic procedures, and the same sort of interface information is needed to resolve such references. This topic is treated in detail in “Defined Operators”.

A third form of generic interface for which explicit interface information is used to resolve references is that of assignment coercion (user-defined assignment). This allows a value of one data type to be converted to a corresponding value of another data type and assigned to an object of the latter type. A simple example of coercion, intrinsic to Fortran, is K = X + 2.2, where X is of type real and K is integer. Examples of desirable new coercions might be R = K where R is of the derived type representing rational numbers and K is an integer, and P = M2D where P is of the derived type representing a two-dimensional picture and M2D is a two-dimensional integer array. These last two effects could also be achieved by subroutine calls, as follows:

CALL RATINT(R, K)
CALL PXINIT(P, M2D)

These coercion operations are performed by the same subroutines, but these subroutines can be invoked by the assignment syntax rather than the traditional subroutine call syntax. This topic is treated in more detail in “Defined Assignment”.

Interface Blocks

A procedure interface block is used to perform the following functions:

  1. Make explicit interfaces for external and dummy procedures.

  2. Define a generic procedure name, specify the set of procedures to which that name applies, and make explicit the interfaces of any external procedures included in the set.

  3. Define a new operator symbol or specify the extension of an intrinsic or already defined operator, identify the function or functions to which it applies, and make explicit the interfaces of any of those functions that are external.

  4. Define one or more new assignment coercions, identify the subroutine or subroutines involved, and make explicit the interfaces of any of those subroutines that are external.

In all of these cases, the purpose of the interface block is to make the necessary information available to the calling routine so that a procedure reference can be processed correctly. Therefore, the interface block must either appear in the specification part of the calling routine or be in a module used by the calling routine.

Of the previous four items, the first is further described in the following sections. The others were described in previous sections. In the following sections, the general form of interface blocks, covering all four of these cases, is described, followed by a discussion of the simplified form that applies to just the first case.

General Form of Procedure Interface Blocks

An interface block has the following general format:

INTERFACE [generic_spec]
[interface_body] ...
[ MODULE PROCEDURE procedure_name_list] ...
END INTERFACE [generic_spec]

Interface blocks are defined as follows:

 

interface_block

is

interface_stmt
[interface_specification] ...
end_interface_stmt

 

interface_specification

is

interface_body

 

 

or

module_procedure_stmt

 

interface_stmt

is

INTERFACE [generic_spec]

 

end_interface_stmt

is

END INTERFACE

 

interface_body

is

function_stmt
[specification_part]
end_function_stmt

 

 

or

subroutine_stmt
[specification_part]
end_subroutine_stmt

 

module_procedure_stmt

is

MODULE PROCEDURE procedure_name_list

 

generic_spec

is

generic_name

 

 

or

OPERATOR (defined_operator)

 

 

or

ASSIGNMENT (=)

An interface_body specifies the interface for either a function or a subroutine.

The following is the general format of a function interface body:

function_statement
[specification_part]
END [ FUNCTION [function_name]]

The following is the general format of a subroutine interface body:

subroutine_statement
[specification_part]
END [ SUBROUTINE [subroutine_name]]

The keyword FUNCTION or SUBROUTINE is optional on an interface body's END statement, but use of these keywords is recommended as an aid to program clarity.

The form without the generic_spec applies to case 1 in the list of four in “Interface Blocks”. The choice of a generic_name for a generic_spec is case 2. The OPERATOR choice for a generic_spec is case 3. The ASSIGNMENT choice for a generic_spec is case 4.

The following guidelines apply to interface blocks:

  1. If the generic_spec is omitted, the interface block must not contain any MODULE PROCEDURE statements.

  2. In all cases, an interface body must be for an external or dummy procedure.

  3. The specification_part of an interface body contains specifications pertaining only to the dummy arguments and, in the case of functions, the function result. This means, for example, that an interface body cannot contain an ENTRY statement, DATA statement, FORMAT statement, or statement function statement.

  4. The attributes of the dummy arguments and function result must be completely specified in the specification part, and these specifications must be consistent with those specified in the procedure definition. Note that dummy argument names may be different, but the attributes must be the same. Also, the interface can specify a procedure that is not pure if the procedure is defined to be PURE.

  5. Because an interface body describes properties defined in an external scope rather than in its host's scope, an interface body comprises its own scoping unit, separate from any other scoping unit; an interface body does not inherit anything from its host via host association, such as named constants nor does it inherit its host's implicit type rules. For example:

    MODULE N
       TYPE :: T
          INTEGER I
       END TYPE
    END MODULE
    PROGRAM P
    USE N
    INTERFACE
       SUBROUTINE S(R)
       USE N     ! NEED THIS STATEMENT TO ACCESS TYPE T.
                 ! IT IS NOT HOST ASSOCIATED.
       TYPE (T) :: R
       END SUBROUTINE
    END INTERFACE
    END PROGRAM

    An interface body may contain a USE statement and access entities, such as derived-type definitions, via use association.

  6. A procedure name in a MODULE PROCEDURE statement must be the name of a module procedure either in that module (if the interface block is contained in a module) or accessible to the program unit containing the interface block through use association. It must not appear in another interface with the same generic specifier in the same scoping unit or in an accessible scoping unit.

  7. An interface_body of a pure procedure must specify the intents of all dummy arguments except POINTER, alternate return, and procedure arguments.

  8. An interface block must not contain an ENTRY statement, but an entry interface can be specified by using the entry name as the function or subroutine name in an interface body.

  9. A procedure must not have more than one explicit specific interface in a given scoping unit.

  10. An interface block must not appear in a block data program unit.

  11. An interface body that describes the program unit being compiled can exist within the program unit.

  12. An interface body can be specified within or USE associated with each program unit being compiled.


Note: The Fortran standard does not allow an interface body for the program unit being compiled within that program unit.


Explicit Interfaces for External Procedures

The simplest use of an interface block is to make the interface for an external or dummy procedure explicit. The format of the interface block for this purpose is as follows:

INTERFACE
interface_body ...
END INTERFACE

Guidelines 2 through 5 and 7 through 9, from “General Form of Procedure Interface Blocks”, apply in this case. Rule 5 means that IMPLICIT statements, type declarations, and derived-type definitions in the host do not carry down into an interface body. Rule 8 means that an interface body for a given external procedure may be specified at most once in a host program unit. It also means that an interface body cannot be specified for intrinsic, internal, and module procedures, because these procedures already have explicit interfaces. This is the reason for the MODULE PROCEDURE statement's existence.

The CF90 and MIPSpro 7 Fortran 90 compilers allow you to specify an interface body for the program unit being compiled.


Note: The Fortran standard does not allow you to specify an interface body for the program unit being compiled.


Generic Procedures

Fortran programmers are familiar with generic procedures because many of the intrinsic procedures in Fortran are generic. The following are examples of generic procedure references:

INT(R)
INT(D)

Assume in the previous example, that R and D are real and double precision objects, respectively. It looks like there is only one procedure involved here (INT), but there are really two. There is a specific procedure that accepts a real argument and another one that accepts a double-precision argument. Because the purpose of these two procedures is virtually identical, it is desirable to refer to each of them with the same generic name. The type of the argument is sufficient to identify which of the specific procedures is involved in a given reference.

Thus, generic refers to a set of different procedures with different specific names that all have the same (generic) name. The mechanism for declaring generic procedures is the interface block, which in this case has the following format:

INTERFACE generic_name
[interface_body] ...
[ MODULE PROCEDURE procedure_name_list] ...
END INTERFACE

Rules and restrictions 2 through 9 in “General Form of Procedure Interface Blocks”, apply in this case. The generic name in the INTERFACE statement, of course, specifies the generic name to be used in this procedure. All the procedures being assigned this generic name are specified in the interface block. This potentially includes both external procedures and module procedures. In the case of an external procedure, the procedure is identified by its specific name and its interface body, thereby making its interface explicit as well as defining a generic name for it. In the case of a module procedure, only the specific name of the procedure is given (in order to identify the procedure) because its interface is already explicit. Note that because of rule 8 an external procedure can be included in only one generic set in a given procedure. Because the MODULE PROCEDURE statement does not specify an explicit interface, however, a module procedure may be included in any number of generic sets.

Note also that internal procedures cannot be given generic names, nor can statement functions. Similarly, intrinsic procedures cannot be included in an interface block, but a generic name may be the same as an intrinsic procedure name, including a generic intrinsic procedure name.

Consider the following example:

INTERFACE INT
   MODULE PROCEDURE RATIONAL_TO_INTEGER
END INTERFACE

The generic properties of the INT intrinsic function are extended to include a user-defined procedure.

The generic name can also be the same as one of the specific names of the procedures included in the generic set, or the same as any other generic name, or completely different. The only real requirement is that any procedure reference involving a generic procedure name be resolvable to one specific procedure. Thus, for example, the generic name INT cannot be applied to a user-defined function that has a single real argument, because then a reference to INT with a real actual argument would be ambiguous as to whether the reference was to the corresponding intrinsic function or to the user-defined function.

The rules for resolving a generic reference involve the number of arguments and the type, kind type parameter, and rank of each argument. Based upon these rules, and only these rules, a given procedure reference must be consistent with precisely one of the specific procedures in the generic set. Consider, for example, a simple two-argument subroutine G(P, Q) with generic name G, dummy argument names P and Q, and neither argument optional. A reference to G, with actual arguments X and Y could take any of the following four forms:

CALL G(X, Y)
CALL G(X, Q=Y)
CALL G(P=X, Q=Y)
CALL G(Q=Y, P=X)

The last three are allowed because the interface to G is explicit and keyword references can be used when the interface is explicit. What subroutine H could be added to the generic set with G? The first of the preceding four calls rules out any two-argument H whose first argument has the same type, kind type parameter, and rank (TKR) as the P argument of G and whose second argument has the same TKR as the Q argument of G. The third and fourth of these four calls rules out any subroutine H of the form H(Q, P), whose first argument is named Q and has the same TKR as the Q (second) argument of G and whose second argument is named P and has the same TKR as the P (first) argument of G. The reason for this last case is that a reference to H in which all the actual arguments had keywords would look exactly like a call to G, in terms of TKR patterns; such a reference would not be uniquely resolvable to either a call to G only or to H only. Any other H could be included in the generic set with G.

Thus, the essence of the generic reference resolution rules is uniqueness with respect to TKR patterns under both positional or keyword references. The complete formal rules for this are described in “Resolving Procedure References” in Chapter 6.

A procedure can always be referenced by its specific name. It can also be referenced by any generic name it might also have been given.

Defined Operators

Just as generic names allow you to give procedures alternative and presumably better forms of reference, so do defined operators. In this case functions of one or two nonoptional arguments are involved.

Often the purpose of a function is to perform some computation (operation) on the values represented by its arguments and to return the result for computational use in the calling program. In mathematical tradition, such operations of one or two arguments are usually expressed as operators in an expression, with the arguments as the operands. A good example is the INVERSE function described in “Operator Extensions” in Chapter 3. The defined operator provisions of the interface block give you the option of specifying a function reference with operator syntax.

The format of the interface block for defining a new operator or extending the generic properties of an existing operator is as follows:

INTERFACE OPERATOR (defined_operator)
[interface_body] ...
[ MODULE PROCEDURE procedure_name_list] ...
END INTERFACE

The same rules apply here as in the generic name case. In addition, each interface body must be for a one- or two-argument function, and each procedure name in the MODULE PROCEDURE statement must be that of a one- or two-argument function. The arguments are all required and all must be specified with INTENT(IN).

The defined operator in the INTERFACE statement specifies the operator that can be used in the operation form of reference for each of the functions identified in the interface block. The operation takes the infix (operator between the arguments) form for two-argument functions and takes the prefix form for one-argument functions.

Consider the following example:

INTERFACE OPERATOR(+)
   FUNCTION INTEGER_PLUS_INTERVAL(X, Y)
      USE INTERVAL_ARITHMETIC
      TYPE(INTERVAL)     :: INTEGER_PLUS_INTERVAL
      INTEGER, INTENT(IN)        :: X
      TYPE(INTERVAL), INTENT(IN) :: Y
   END FUNCTION INTEGER_PLUS_INTERVAL
   MODULE PROCEDURE RATIONAL_ADD
END INTERFACE

This code extends the + operator to two user-defined functions, an external function INTEGER_PLUS_INTERVAL that presumably computes an appropriate value for the sum of an integer value and something called an interval, and a module function RATIONAL_ADD that probably computes the sum of two rational numbers. Both functions now can be called in the form A+B, where A and B are the two actual arguments.

The following example shows a new operator being defined, rather than extending an existing operator:

INTERFACE OPERATOR(.INVERSETIMES.)
    MODULE PROCEDURE MATRIX_INVERSE_TIMES
END INTERFACE

In this example, the inverse of matrix A can be multiplied by B using the expression A .INVERSETIMES. B, which produces A-1xB, and in effect solves the system of linear equations, Ax=B, for x.

Functions with operator interfaces can be referenced with the operator form, but they also can be referenced through the traditional functional form by using the specific function name.

The two forms for a defined operator are as follows:

intrinsic_operator
.letter[letter] ... .

Note that these are the same as some of the intrinsic operators and that neither .TRUE. nor .FALSE. can be chosen as a defined operator. Note also that if an operator has the same name as a standard intrinsic operator, it must have the same number of operands as the intrinsic operator; for example, .NOT. must not be defined as a binary operator. The masking or boolean operators that are extensions to the Fortran standard can be redefined in an interface. In this case, your definition overrides the masking operator.

Operator interfaces define a set of generic procedures, with the operator being the generic name. This is particularly obvious with intrinsic operators, as each intrinsic operation may be thought of as being performed by a hidden intrinsic function and the operator interface merely extends the set of functions that share that operator form. As with the use of generic procedure names, a function reference through a generic operator must resolve to a unique specific function. The resolution rules in this case are exactly the same TKR rules used for the generic name case when the functional form is used (see the previous section), but are somewhat simpler when the operator syntax is used because this syntax does not allow the use of argument keywords. Thus, the argument TKR pattern must be unique solely on the basis of argument position.

This means, for example, that + cannot be specified in an operator interface for a function with a scalar integer argument and a scalar real argument because + already has a meaning for any such TKR pattern. Specifying such an operator extension would mean that I+R, where I is a scalar integer and R is a scalar real, would be ambiguous between the intrinsic meaning and the extended meaning. Therefore, the TKR rules disallow such extensions.

Defined Assignment

The last form of generic procedures is assignment (or conversion) subroutines. These specify the conversion of data values with one set of TKR attributes into another set with a different pattern of TKR attributes. Although such conversions can be performed by ordinary subroutines, it is convenient and natural to express their use with assignment syntax, and hence defined assignment extensions. If you want to think of assignment as an operation, then defined assignment is precisely the same as defined operators, except that there is only one defined assignment operator symbol (=), and all defined assignment procedures are two-argument subroutines rather than functions. As with the other forms of generic procedures, the interface block is used to specify defined assignments.

The format of the interface block for defining new assignment operations is as follows:

INTERFACE ASSIGNMENT (=)
[interface_body] ...
[ MODULE PROCEDURE procedure_name_list] ...
END INTERFACE

Again, most of the same rules apply here as in the generic name case, except that each interface body must be for a two-argument external subroutine and each procedure name in the MODULE PROCEDURE statement must be that of an accessible two-argument module subroutine. Both arguments are required. The first argument must have the attribute INTENT(OUT) or INTENT(INOUT); this is the location for the converted value. The second argument must have the attribute INTENT(IN); this is the value to be converted.

The assignment interface specifies that an assignment statement can be used in place of a traditional subroutine call for the subroutines identified in the interface block.

Recall that an assignment statement is defined as follows:

variable = expression

The variable would be the first actual argument in a traditional call to the subroutine and the expression would be the second argument. The variable must be a variable designator legitimate for the left-hand side of an assignment.

You can use the traditional subroutine call or the assignment syntax.

An example of an assignment interface block is as follows:

INTERFACE ASSIGNMENT(=)
   SUBROUTINE ASSIGN_STRING_TO_CHARACTER(C, S)
      USE STRING_DATA
      CHARACTER(*), INTENT(OUT) :: C
      TYPE(STRING), INTENT(IN)  :: S
   END SUBROUTINE ASSIGN_STRING_TO_CHARACTER
   MODULE PROCEDURE  RATIONAL_TO_INTEGER
END INTERFACE

This interface block allows ASSIGN_STRING_TO_CHARACTER (which extracts the character value) to be called in the following form:

C = S

In addition, RATIONAL_TO_INTEGER can be called in the following format:

K = R

Here, R is of derived type RATIONAL and K is an integer. The purpose of RATIONAL_TO_INTEGER is to convert a value in RATIONAL form into an integer.

Each intrinsically defined assignment operation may be thought of as being performed by a hidden intrinsic subroutine. Thus, the assignment symbol is the generic name of a set of generic subroutines. The assignment interface block allows you to add user-defined external and module subroutines to that generic set. Any given assignment must be resolvable to the specific subroutine. Not surprisingly, when assignment syntax is used, it is the TKR pattern rules without the keyword argument complication that are applied to perform this resolution, exactly as with defined operators.

This means, for example, that an assignment interface cannot be specified for a subroutine whose first argument is a scalar of type integer and whose second argument is a scalar of type real. All such coercions have intrinsic meanings, and thus an assignment interface block of this form would introduce an unresolvable ambiguity. The TKR rules prevent this from happening.