XL Fortran for AIX 8.1

Language Reference

+---------------------------------Fortran 95---------------------------------+


Pure Procedures

Because PURE procedures are free of side effects, the compiler is not constrained to invoke them in any particular order. Exceptions to this are as follows:

Pure procedures 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:

Intrinsic functions (except RAND, an XL Fortran extension) and the MVBITS subroutine are always pure. They do not need to be explicitly declared to have the PURE attribute. 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 of 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 argument. 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 of 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 storage associated with a global variable, or a subobject thereof, in the following contexts:

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 cannot be an asterisk (*) or refer to an external unit. The input/output statements are BACKSPACE, ENDFILE, REWIND, OPEN, CLOSE, INQUIRE, READ, PRINT, and WRITE. The PAUSE and STOP statements are not permitted in pure procedures.

There are two differences between pure functions and pure subroutines:

  1. Subroutine nonpointer dummy data objects may have any intent, while function nonpointer dummy data objects must have an intent of IN
  2. Subroutine dummy data objects with the POINTER attribute may 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).

Examples

PROGRAM ADD
  INTEGER ARRAY(20,256)
  INTERFACE                              ! Interface required for
    PURE FUNCTION PLUS_X(ARRAY)          !   a pure procedure
      INTEGER, INTENT(IN) :: ARRAY(:)
      INTEGER :: PLUS_X(SIZE(ARRAY))
    END FUNCTION
  END INTERFACE
  INTEGER :: X
  X = ABS(-4)                            ! Intrinsic function
                                         !   is always pure
  FORALL (I=1:20, I /= 10)
    ARRAY(I,:) = I + PLUS_X(ARRAY(I,:))  ! Procedure references in
                                         !   FORALL must be pure
  END FORALL
END PROGRAM
PURE FUNCTION PLUS_X(ARRAY)
  INTEGER, INTENT(IN) :: ARRAY(:)
  INTEGER :: PLUS_X(SIZE(ARRAY)),X
  INTERFACE
    PURE SUBROUTINE PLUS_Y(ARRAY)
      INTEGER, INTENT(INOUT) :: ARRAY(:)
    END SUBROUTINE
  END INTERFACE
  X=8
  PLUS_X = ARRAY+X
  CALL PLUS_Y(PLUS_X)
END FUNCTION
 
PURE SUBROUTINE PLUS_Y(ARRAY)
  INTEGER, INTENT(INOUT) :: ARRAY(:)     ! Intent must be specified
  INTEGER :: Y
  Y=6
  ARRAY = ARRAY+Y
END SUBROUTINE

+-----------------------------End of Fortran 95------------------------------+


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]