A PROCEDURE statement declares a dummy procedure, an external procedure, or a procedure pointer. It specifies the EXTERNAL attribute for these entities.
>>-PROCEDURE--(--+---------------------+--)--+---------------------------------+--> '-procedure_interface-' +-::------------------------------+ '-,--procedure_attribute_list--::-' .-,----------------------------------------. V | >----procedure_entity_name--+---------------+-+---------------->< '-=>--null_init-'
where:
If procedure_interface is the name of a procedure or procedure pointer that has an explicit interface, the declared procedures or procedure pointers have this explicit interface. The referenced procedure or procedure pointer must already be declared. The referenced procedure must not be an intrinsic procedure and its name cannot be the same as a keyword that specifies an intrinsic type. If the referenced procedure is an elemental procedure, the procedure entity names must consist of external procedures.
If procedure_interface is a declaration type specifier, the declared procedures or procedure pointers are functions with an implicit interface and the specified result type. If these functions are external functions, the function definitions must specify the same result type and type parameters.
If no procedure_interface is specified, the PROCEDURE statement specifies that the declared procedures or procedure pointers are either subroutines or functions. If they are functions, the implicit type rule applies to the type of the function.
If you specify procedure language binding using the BIND attribute, procedure_interface must be the name of a procedure or procedure pointer that is declared with procedure language binding.
If procedure language binding with NAME= is specified, the procedure entity name must consist of only one procedure entity name. This procedure must not be a dummy procedure or have the POINTER attribute.
If OPTIONAL is specified, the declared procedures or procedure pointers must be dummy procedures or procedure pointers.
You can only specify PUBLIC or PRIVATE if the statement appears in the specification part of a module.
If INTENT, SAVE, or null_init is specified, the declared entities must have the POINTER attribute.
If null_init is used, it specifies that the initial association status of the corresponding procedure pointer is disassociated. It also implies the SAVE attribute, which can be reaffirmed by explicitly using the SAVE attribute in the procedure declaration statement or by a SAVE statement.
For procedure pointer declarations, you must specify the POINTER attribute. For declarations of procedure pointer components of derived types, you must specify the NOPASS attribute.
Example 1
The following example shows an external procedure declaration.
CONTAINS SUBROUTINE XXX(PSI) PROCEDURE (REAL) :: PSI REAL Y1 Y1 = PSI() END SUBROUTINE END
Example 2
The following example shows a procedure pointer declaration and its use.
PROGRAM PROC_PTR_EXAMPLE REAL :: R1 INTEGER :: I1 INTERFACE SUBROUTINE SUB(X) REAL, INTENT(IN) :: X END SUBROUTINE SUB FUNCTION REAL_FUNC(Y) REAL, INTENT(IN) :: Y REAL, REAL_FUNC END FUNCTION REAL_FUNC END INTERFACE PROCEDURE(SUB), POINTER :: PTR_TO_SUB ! with explicit interface PROCEDURE(REAL_FUNC), POINTER :: PTR_TO_REAL_FUNC => NULL() ! with explicit interface PROCEDURE(INTEGER), POINTER :: PTR_TO_INT ! with implicit interface PTR_TO_SUB => SUB PTR_TO_REAL_FUNC => REAL_FUNC CALL PTR_TO_SUB(1.0) R1 = PTR_TO_REAL_FUNC(2.0) I1 = PTR_TO_INT(M, N) END PROGRAM PROC_PTR_EXAMPLE