Intel® Fortran Compiler 16.0 User and Reference Guide

Type-Bound Procedures

In a derived-type definition, you can optionally specify a type-bound-procedure-part, which consists of a CONTAINS statement, optionally followed by a PRIVATE statement, and one or more procedure binding statements. Specific, GENERIC, and FINAL procedure bindings are defined below.

A type-bound-procedure-part in a derived-type definition takes the following form:

CONTAINS
[PRIVATE]
proc-binding-stmt
[ proc-binding-stmt]...

proc-binding-stmt

Is one of the following:

  • specific-binding

  • generic-binding

  • final-binding

The default accessibility of type-bound procedures is public even if the components are private. You can change this by including the PRIVATE statement following the CONTAINS statement.

specific-binding
A specific type-bound procedure binds a procedure to a type or it specifies a deferred binding to an abstract type. It takes the following form:

PROCEDURE [ (interface-name) ] [ [ , binding-attr-list ] :: ] binding-name [ => procedure-name ]

interface-name

(Optional) Is the interface for the procedure. It must be the name of an abstract interface or a procedure that has an explicit interface. interface-name can only be specified if the binding has the DEFERRED attribute.

binding-attr-list

(Optional) Is one or more of the following. The same attribute can only appear once for the same binding:

  • PASS

    Defines the "passed-object dummy argument" of the procedure.

  • NOPASS

    Indicates that the procedure has no passed-object dummy argument. Use this keyword if the procedure pointer component has an implicit interface or has no arguments. PASS and NOPASS can not both be specified for the same binding.

  • access-spec

    Is the PUBLIC or PRIVATE attribute.

  • NON_OVERRIDABLE

    Determines whether a binding can be overridden in an extended type. You must not specify NON_OVERRIDABLE for a binding with the DEFERRED attribute.

  • DEFERRED

    Indicates that the procedure is deferred. Deferred bindings must only be specified for derived-type definitions with the ABSTRACT attribute. A procedure with the DEFERRED binding attribute must specify an interface_name. An overriding binding can have the DEFERRED attribute only if the binding it overrides is deferred. The NON_OVERRIDABLE and DEFERRED binding attributes must not both be specified for the same procedure.

binding-name

Is the name of the type-bound procedure. It is referred to in the same way as a component of a type.

procedure-name

(Optional) Is the name of the actual procedure which implements binding-name. It is the name of an accessible module procedure or an external procedure that has an explicit interface. It defines the interface for the procedure, and the procedure to be executed when the procedure is referenced.

If neither =>procedure-name nor interface-name appears, the procedure-name is the same as the binding-name. If =>procedure-name appears, you must specify the double-colon separator and you must not specify an interface-name.

In general, the invoking variable, the passed-object dummy argument, is passed as an additional argument. By default, this is the first dummy argument of the actual procedure. So, the first argument in the argument list becomes the second argument, etc.

A passed-object dummy argument can be changed by declaring the type-bound procedure with the PASS(arg-name) attribute. In this case, the variable is passed as the named argument. The PASS attribute can also be used to confirm the default as the first argument. The NOPASS attribute prevents passing the object as an argument.

Consider the following:

TYPE MY_TYPE
...   ! Component declarations
CONTAINS
  PROCEDURE :: PROC1 => MY_PROC
  PROCEDURE :: PROC2
END TYPE MY_TYPE

This binds MY_PROC with the PROC1.

If B is a scalar variable of type MY_TYPE, an example of a type-bound call is:

CALL B%PROC1(C, D)

When PASS is in effect, the call passes B to the first argument of the procedure, C to the second argument, and D to the third argument.

generic-binding
A generic type-bound procedure defines a generic interface that is bound to the type. It takes the following form:

GENERIC [, access-spec ] :: generic-spec => binding-name1 [, binding-name2]...

access-spec

Is the PUBLIC or PRIVATE attribute. Only one can be specified.

generic-spec

Is an explicit INTERFACE statement using one of the following:

The same generic-spec can be used in several generic bindings within a single derived-type definition. In this case, every occurrence of the same generic-spec must have the same accessibility.

binding-name1, binding-name2, ...

Is the name of the type-bound procedure. Each specific binding-name must have the passed-object dummy argument.

Consider the following:

TYPE MY_TYPE2
...   
CONTAINS
  PROCEDURE :: MYPROC => MYPROC1
  PROCEDURE,PASS(C) :: UPROC => UPROC1
  GENERIC :: OPERATOR(+) => MYPROC, UPROC
END TYPE MY_TYPE2
...
TYPE,EXTENDS(MY_TYPE2) :: MY_TYPE3
...
CONTAINS
  PROCEDURE :: MYPROC => MYPROC2
  PROCEDURE,PASS(C) :: UPROC => UPROC2
END TYPE MY_TYPE3

The type MY_TYPE3 inherits the generic operator '+'. Invoking the generic (+) invokes the specific type-bound procedure. For entities of type MY_TYPE3, that invokes the overriding actual procedure (MYPROC2 or UPROC2).

final-binding
An extensible derived type can have one or more "final subroutines" associated with it. A final subroutine can be executed to perform clean-up operations after a data entity of that type is finalized (ceases to exist).

A finalization procedure defines one or more final subroutines that are bound to the type. It takes the following form:

FINAL [ :: ] sub1 [, sub2]...

sub1, sub2, ...

Is a final subroutine, which is a module procedure with exactly one dummy argument of the derived type. The dummy argument cannot be INTENT(OUT), it cannot be optional, and it cannot be a pointer or allocatable. All array shape and length type parameters are assumed.

A final subroutine must not have a dummy argument with the same kind type parameters and rank as the dummy argument of another final subroutine of the type.

You cannot specify a subroutine that was previously specified as a final subroutine for the derived type.

The following example declares two module subroutines to be final:

TYPE MY_TYPE
...   ! Component declarations
CONTAINS
  FINAL :: CLEAN1, CLEAN2
END TYPE MY_TYPE

See Also