Lahey/Fujitsu Fortran

Procedure Interfaces

A procedure interface is all the characteristics of a procedure that are of interest to the Fortran processor when the procedure is invoked. These characteristics include the name of the procedure, the number, order, type parameters, shape, and intent of the arguments; whether the arguments are optional, and whether they are pointers; and, if the reference is to a function, the type, type parameters, and rank of the result, and whether it is a pointer. If the function result is not a pointer, its shape is an important characteristic. The interface can be explicit, in which case the Fortran processor has access to all characteristics of the procedure interface, or implicit, in which case the Fortran processor must make assumptions about the interface.

Explicit Interfaces

It is desirable, to avoid errors, to have interfaces available whenever possible. In each of the following cases, an interface is mandatory:

An interface is always explicit for intrinsic procedures, internal procedures, and module procedures. A statement function's interface is always implicit. In other cases, explicit interfaces can be established using an interface block.

Syntax:

interface-stmt [interface-body] ... [module procedure statement] ... end-interface statement Where: interface-stmt is an interface statement. interface-body is function-stmt [specification-part] end-stmt or subroutine-stmt [specification-part] end-stmt module-procedure-stmt is a module procedure statement. end-interface-stmt is an end interface statement. function-stmt is a function statement. subroutine-stmt is a subroutine statement. specification-part is the specification part of the procedure. end-stmt is an end statement.

Example:

interface subroutine x(a, b, c) implicit none real, intent(in), dimension (2,8) :: a real, intent(out), dimension (2,8) :: b, c end subroutine x function y(a, b) implicit none logical, intent(in) :: a, b end function y end interface

In this example, explicit interfaces are provided for the procedures x and y. Any errors in referencing these procedures in the scoping unit of the interface block will be diagnosed at compile time.

Generic Interfaces

An interface statement with a generic-name (see Interface Block) specifies a generic interface for each of the procedures in the interface block. In this way external generic procedures can be created, analogous to intrinsic generic procedures.

Example:

interface swap ! generic swap routine subroutine real_swap(x, y) implicit none real, intent(in out) :: x, y end subroutine real_swap subroutine int_swap(x, y) implicit none integer, intent(in out) :: x, y end subroutine int_swap end interface

Here the generic procedure swap can be used with both the real and integer types.

Defined Operations

Operators can be extended and new operators created for user-defined and intrinsic data types. This is done using interface blocks with interface operator (see Interface Block).

A defined operation has the form

operator operand

for a defined unary operation, and

operand operator operand

for a defined binary operation, where operator is one of the intrinsic operators or a user-defined operator of the form

.operator-name.

where .operator-name. consists of one to 31 letters.

for example, either

a .intersection. b

or

a * b

might be used to indicate the intersection of two sets. The generic interface block might look like

    interface operator (.intersection.)
       function set_intersection (a, b)
          implicit none
          type (set), intent(in) :: a, b, set_intersection
       end function set_intersection
    end interface
 

for the first example, and

    interface operator (*)
       function set_intersection (a, b)
          implicit none
          type (set), intent(in) :: a, b, set intersection
       end function set_intersection
    end interface
 

for the second example. The function set_intersection would then contain the code to determine the intersection of a and b.

The precedence of a defined operator is the same as that of the corresponding intrinsic operator if an intrinsic operator is being extended. If a user-defined operator is used, a unary defined operation has higher precedence than any other operation, and a binary defined operation has a lower precedence than any other operation.

An intrinsic operation (such as addition) cannot be redefined for valid intrinsic operands. for example, it is illegal to redefine plus to mean minus for numeric types.

The functions specified in the interface block take either one argument, in the case of a defined unary operator, or two arguments, for a defined binary operator. The operand or operands in a defined operation become the arguments to a function specified in the interface block, depending on their type, kind, and rank. If a defined binary operation is performed, the left operand corresponds to the first argument and the right operand to the second argument. Both unary and binary defined operations for a particular operator may be specified in the same interface block.

Defined Assignment

The assignment operator may be extended using an interface block with interface assignment (see see Interface Block). The mechanism is similar to that used to resolve a defined binary operation (see Defined Operations), with the variable on the left side of the assignment corresponding to the first argument of a subroutine in the interface block and the data object on the right side corresponding to the second argument. The first argument must be intent(out) or intent(in out); the second argument must be intent(in).

Example:

interface assignment (=) ! use = for integer to logical array subroutine integer_to_logical_array (b, n) implicit none logical, intent(out) :: b(:) integer, intent(in) :: n end subroutine integer_to_logical_array end interface

Here the assignment operator is extended to convert integer data to a logical array.