Generic interface blocks
In an INTERFACE statement, a generic interface block must specify
one of the following:
- a generic name
- defined operator
- defined assignment
The generic name is a single name with which to reference all of the
procedures specified in the interface block. It can be the same as any accessible
generic name, or any of the procedure names in the interface block.
If two or more generic interfaces that are accessible in a scoping unit
have the same local name, they are interpreted as a single generic interface.
Unambiguous generic procedure references
Whenever a generic procedure reference is made, only one specific procedure
is invoked. The following rules ensure that a generic reference is unambiguous.
If two procedures in the same scoping unit both define assignment or both
have the same defined operator and the same number of arguments, you must
specify a dummy argument that corresponds by position in the argument list
to a dummy argument of the other.
Fortran 2003 Standard
Within a scoping unit, two procedures that have the same generic name must
both be subroutines or both be functions.
End of Fortran 2003 Standard
When an interface block extends an intrinsic procedure (see the next section),
the above rules apply as if the intrinsic procedure consisted of a collection
of specific procedures, one procedure for each allowed set of arguments.
IBM Extension
Notes:
- Dummy arguments of type BYTE are considered to have the same
type as corresponding 1-byte dummy arguments of type INTEGER(1), LOGICAL(1), and character.
- When the -qintlog compiler option is specified, dummy arguments
of type integer and logical are considered to have the same type as corresponding
dummy arguments of type integer and logical with the same kind type parameter.
- If the dummy argument is only declared with the EXTERNAL attribute
within an interface body, the dummy argument must be the only dummy argument
corresponding by position to a procedure, and it must be the only dummy argument
corresponding by argument keyword to a procedure.
End of IBM Extension
Example of a generic interface block
PROGRAM MAIN
INTERFACE A
FUNCTION AI(X)
INTEGER AI, X
END FUNCTION AI
END INTERFACE
INTERFACE A
FUNCTION AR(X)
REAL AR, X
END FUNCTION AR
END INTERFACE
INTERFACE FUNC
FUNCTION FUNC1(I, EXT) ! Here, EXT is a procedure
INTEGER I
EXTERNAL EXT
END FUNCTION FUNC1
FUNCTION FUNC2(EXT, I)
INTEGER I
REAL EXT ! Here, EXT is a variable
END FUNCTION FUNC2
END INTERFACE
EXTERNAL MYFUNC
IRESULT=A(INTVAL) ! Call to function AI
RRESULT=A(REALVAL) ! Call to function AR
RESULT=FUNC(1,MYFUNC) ! Call to function FUNC1
END PROGRAM MAIN
Extending intrinsic procedures with generic interface blocks
A generic intrinsic procedure can be extended or redefined. An extended
intrinsic procedure supplements the existing specific intrinsic procedures.
A redefined intrinsic procedure replaces an existing specific intrinsic procedure.
When a generic name is the same as a generic intrinsic procedure name and
the name has the INTRINSIC attribute (or appears in an intrinsic
context), the generic interface extends the generic intrinsic procedure.
When a generic name is the same as a generic intrinsic procedure name and
the name does not have the INTRINSIC attribute (nor appears in an
intrinsic context), the generic interface can redefine the generic intrinsic
procedure.
A generic interface name cannot be the same as a specific intrinsic procedure
name if the name has the INTRINSIC attribute (or appears in an intrinsic
context).
Example of extending and redefining intrinsic procedures
PROGRAM MAIN
INTRINSIC MAX
INTERFACE MAX ! Extension to intrinsic MAX
FUNCTION MAXCHAR(STRING)
CHARACTER(50) STRING
END FUNCTION MAXCHAR
END INTERFACE
INTERFACE ABS ! Redefines generic ABS as
FUNCTION MYABS(ARG) ! ABS does not appear in
REAL(8) MYABS, ARG ! an INTRINSIC statement
END FUNCTION MYABS
END INTERFACE
REAL(8) DARG, DANS
REAL(4) RANS
INTEGER IANS,IARG
CHARACTER(50) NAME
DANS = ABS(DARG) ! Calls external MYABS
IANS = ABS(IARG) ! Calls intrinsic IABS
DANS = DABS(DARG) ! Calls intrinsic DABS
IANS = MAX(NAME) ! Calls external MAXCHAR
RANS = MAX(1.0,2.0) ! Calls intrinsic AMAX1
END PROGRAM MAIN
Defined operators
A defined operator is a user-defined unary or binary operator, or an extended
intrinsic operator (see Extended intrinsic and defined operations). It must be defined by both
a function and a generic interface block.
- To define the unary operation op x1:
- A function or entry must exist that specifies exactly one dummy argument, d1.
-
- the generic_spec in an INTERFACE statement specifies OPERATOR (op), or
- The type of x1 is the type of the dummy argument d1.
- The type parameters, if any, of x1 must match those of d1.
- Either
- The function is ELEMENTAL, or
- The rank of x1, and its shape, if it is an array, match
those of d1
- To define the binary operation x1 op x2:
- The function is specified with a FUNCTION or ENTRY statement
that specifies two dummy arguments, d1 and d2.
-
- the generic_spec in an INTERFACE block specifies OPERATOR (op), or
- The types of x1 and x2 are the types of the dummy arguments d1 and d2, respectively.
- The type parameters, if any, of x1 and x2 match
those of d1 and d2, respectively.
- Either:
- The function is ELEMENTAL and x1 and x2 are conformable or,
- The ranks of x1 and x2 and their shapes, if
either or both are arrays, match those of d1 and d2, respectively.
- If op is an intrinsic operator, the types or ranks of either x1 or x2 are not those required for an intrinsic operation.
- The generic_spec must not specify OPERATOR for functions
with no arguments or for functions with more than two arguments.
- Each argument must be nonoptional.
- The arguments must be specified with INTENT(IN).
- If the operator specified is an intrinsic operator, the number of function
arguments must be consistent with the intrinsic uses of that operator.
- A given defined operator can, as with generic names, apply to more than
one function, in which case it is generic just like generic procedure names.
For intrinsic operator symbols, the generic properties include the intrinsic
operations they represent.
- The following rules apply only to extended
intrinsic operations:
- The type of one of the arguments can only be of type BYTE when
the type of the other argument is of derived type.
- When the -qintlog compiler option has been specified for non-character
operations, and d1 is numeric or logical, then d2 must
not be numeric or logical.
- When the -qctyplss compiler option has been specified for non-character
operations, if x1 is numeric or logical and x2 is
a character constant, the intrinsic operation is performed.
Example of a defined operator
INTERFACE OPERATOR (.DETERMINANT.)
FUNCTION IDETERMINANT (ARRAY)
INTEGER, INTENT(IN), DIMENSION (:,:) :: ARRAY
INTEGER IDETERMINANT
END FUNCTION
END INTERFACE
END
Defined assignment
A defined assignment is treated as a reference to a subroutine, with the
left-hand side as the first argument and the right-hand side enclosed in parentheses
as the second argument.
- To define the defined assignment x1 = x2:
- The subroutine is specified with a SUBROUTINE or ENTRY statement
that specifies two dummy arguments, d1 and d2.
-
- the generic_spec of an interface block specifies ASSIGNMENT
(=), or
- The type parameters, if any, of x1 and x2 match
those of d1 and d2, respectively.
- Either:
- The subroutine is ELEMENTAL and either x1 and x2 have the same shape, x2 is scalar, or
- The ranks of x1 and x2, and their shapes,
if either or both are arrays, match those of d1 and d2, respectively.
- ASSIGNMENT must only be used for subroutines with exactly two
arguments.
- Each argument must be nonoptional.
- The first argument must have INTENT(OUT) or INTENT(INOUT), and the second argument must have INTENT(IN).
- The types of the arguments must not be both numeric, both logical,
or both character with the same kind parameter.
IBM Extension
The type of one of the arguments can only be of type BYTE when the type of the other argument is of derived type.
When the -qintlog compiler option has been specified,
and d1 is numeric or logical, then d2 must not
be numeric or logical.
When the -qctyplss compiler option has been specified,
if x1 is numeric or logical and x2 is a character
constant, intrinsic assignment is performed.
End of IBM Extension
- The ASSIGNMENT generic specification specifies that the assignment
operation is extended or redefined if both sides of the equal sign are of
the same derived type.
Example of defined assignment
INTERFACE ASSIGNMENT(=)
SUBROUTINE BIT_TO_NUMERIC (N,B)
INTEGER, INTENT(OUT) :: N
LOGICAL, INTENT(IN), DIMENSION(:) :: B
END SUBROUTINE
END INTERFACE