Pure procedures are free of side effects and are particularly useful
in FORALL statements
and constructs, which by design require that all referenced procedures
be free of side effects.
A procedure must be pure in the following contexts:
- An internal procedure of a pure procedure
- A procedure referenced in the scalar_mask_expr or
body of a FORALL statement
or construct, including one referenced by a defined operator, defined
assignment, or finalization
- A procedure referenced in a pure procedure
- A procedure actual argument to a pure procedure
Intrinsic functions (except RAND,
an XL Fortran extension)
and the MOVE_ALLOC and MVBITS subroutines
are always pure. They do not need to be explicitly declared to be
pure. A statement function is pure if and only if all functions that
it references are pure.
The specification_part of a pure function
must specify that all dummy arguments have an INTENT(IN),
except procedure arguments, and arguments with the POINTER attribute.
The specification_part of a pure subroutine
must specify the intents of all dummy arguments, except for procedure
arguments, asterisks, and arguments that have the POINTER attribute.
Any interface body for such pure procedures must similarly specify
the intents of its dummy arguments.
The
execution_part and
internal_subprogram_part of
a pure procedure cannot refer to a dummy argument with an
INTENT(IN),
a global variable (or any object that is storage associated with one),
or any subobject thereof, in contexts that may cause its value to
change: that is, in contexts that produce side effects. The
execution_part and
internal_subprogram_part of
a pure function must not use a dummy argument, a global variable,
or an object that is associated with a global variable, or a subobject
thereof, in the following contexts:
- As variable in an assignment statement,
or as expression in an assignment statement
if variable is of a derived type that has
a pointer component at any level
- As pointer_object or target in
a pointer assignment statement
- As a DO or
implied-DO variable
- As an input_item in a READ statement
- As an internal file identifier in a WRITE statement
- As an IOSTAT=, SIZE= or IOMSG= specifier
variable in an input/output statement
- As a variable in an ALLOCATE, DEALLOCATE, NULLIFY,
or ASSIGN statement
- As an actual argument that is associated with a dummy argument
with the POINTER attribute
or with an intent of OUT or INOUT
- As the argument to LOC
- As a STAT= or ERRMSG= specifier
- As a variable in a NAMELIST which
appears in a READ statement
- A variable that is the selector in a SELECT TYPE or ASSOCIATE construct
if the associate name of that construct appears in a variable definition
context.
A pure procedure must not specify that any entity is VOLATILE.
In addition, it must not contain any references to data that is VOLATILE,
that would otherwise be accessible through use- or host-association.
This includes references to data which occur through NAMELIST
I/O.
Only internal input/output is permitted in pure procedures. Therefore,
the unit identifier of an input/output statement must not be an asterisk
(*) or refer to an external unit. The input/output statements are:
The
PAUSE and
STOP statements
are not permitted in pure procedures.
There are two differences between pure functions and pure subroutines:
- Subroutine nonpointer dummy data objects may have any intent,
while function nonpointer dummy data objects must be INTENT(IN).
- Subroutine dummy data objects with the POINTER attribute
can change association status and/or definition status
If a procedure is not defined as pure, it must not be declared
pure in an interface body. However, the converse is not true: if a
procedure is defined as pure, it does not need to be declared pure
in an interface body. Of course, if an interface body does not declare
that a procedure is pure, that procedure (when referenced through
that explicit interface) cannot be used as a reference where only
pure procedure references are permitted (for example, in a FORALL statement).