Intel® Fortran Compiler 17.0 Developer Guide and Reference
A separate module procedure is a module procedure that is declared in a separate interface body. To denote separate module procedures, you must specify the keyword MODULE as a prefix in the initial statement of both of the following:
A separate module procedure body
A separate interface body
The interface block that contains the separate interface body must be nonabstract.
A separate interface body can be declared in a module or a submodule. The corresponding separate module procedure may be defined (implemented) in the same module or submodule or a descendent of the module or submodule. A separate module procedure can only be defined once.
Usually, the separate interface body is specified in a module and the separate module procedure is defined in a descendent submodule.
In the following example, FOO is a separate module procedure whose interface is specified in module M while the procedure body is defined in submodule A:
module M
type tt
real r
end type tt
interface
real module function FOO (arg)
type(tt), intent(in) :: arg
end function FOO
end interface
end module M
submodule (M) A
contains
real module function FOO (arg) result(res)
type(tt), intent(in) :: arg
res = arg%r
end function FOO
end submodule A
A separate module procedure is accessible by use association only if its interface body is declared in a module and it is public (for example, FOO in the above example). If a separate module interface is declared in a submodule, the module procedure is only accessible in that submodule or its descendent submodules.
A separate module procedure interface body (either in a module or submodule) has access to entities in its host through host association.
For an interface body that is not a separate interface body, IMPORT statements are required to make entities accessible by host association. However, IMPORT statements are not permitted in a separate interface body.
The initial statement of a separate module procedure body can take one of the two following forms:
MODULE appears as a prefix for a FUNCTION or SUBROUTINE statement
The following shows an example using this form:
submodule (M) A
contains
real module function foo (arg) result(res)
type(tt), intent(in) :: arg
res = arg%r
end function foo
end submodule A
With this form, a separate module procedure must specify the same characteristics and dummy argument names as its corresponding separate interface body.
They must both be functions or subroutines; they must both be pure or not; they must both be elemental or not. The characteristics of its dummy arguments and the characteristics of the function result must also be the same.
RECURSIVE can appear only if RECURSIVE appears as a prefix in the corresponding separate interface body.
Note that the restrictions of matching dummy argument names and matching PURE and RECURSIVE specifications only apply to separate module procedures. For an external procedure, the procedure definition and its interface body can differ with regard to dummy argument names, to whether it is pure, and to whether it is recursive.
A procedure defined in a submodule with the BIND attribute cannot have a binding label (that is, BIND(C, NAME="a-binding-label") unless it is a separate module procedure and its interface is declared in the ancestor module. The binding label specified in a separate module procedure definition must match the binding label specified in the separate interface body.
For this form, the result variable name for a function is determined by the FUNCTION statement in the module subprogram. The result variable name in the interface is ignored.
MODULE PROCEDURE statement
This has the following form:
MODULE PROCEDURE procedure-name [specification-part] [execution-part] [internal-subprogram-part] END [PROCEDURE [procedure-name]]
The following shows an example using this form:
submodule (M) A contains module procedure foo foo = arg%r end procedure foo end submodule A
This syntax avoids the redeclaration of the function or subroutine in the separate module procedure definition and just takes the characteristics, dummy argument names, and the function result variable name from the separate interface body.
A separate module procedure does not have to be defined. The separate module procedure interface can be used to specify an explicit interface; however, the procedure must not be called.
Two modules cannot have USE statements that reference each other because circular reference is not allowed. However, you can solve that problem by putting at least one side of the USEs in submodules. This is because submodules cannot be referenced by use association and the USE statements in submodules are effectively hidden.
See the examples in SUBMODULE.