Developer Guide and Reference

ID 767251
Date 10/31/2024
Public
Document Table of Contents

PRIVATE Statement

Statement and Attribute: Specifies that entities in a module can be accessed only within the module itself.

The PRIVATE attribute can be specified in a type declaration statement or a PRIVATE statement, and takes one of the following forms:

Type Declaration Statement:

type,[att-ls,] PRIVATE [, att-ls] :: entity[, entity]...

Statement:

PRIVATE [[::] entity[, entity] ...]

type

Is a data type specifier.

att-ls

Is an optional list of attribute specifiers.

entity

Is one of the following:

  • A variable name

  • A procedure name

  • A derived type name

  • A named constant

  • A namelist group name

  • An OpenMP* reduction-identifier

In statement form, an entity can also be one of the following:

  • A module name

  • A generic name

  • A defined operator

  • A defined assignment

  • A defined I/O generic specification

Description

The PRIVATE attribute can only appear in the scoping unit of a module.

Only one PRIVATE statement without an entity list is permitted in the scoping unit of a module; it sets the default accessibility of all entities in the module and any entities accessed from a module by USE association whose names do not appear in a PUBLIC statement.

A module name can appear at most once in all the PUBLIC or PRIVATE statements in a scoping unit. If a module name is specified in a PRIVATE statement, the module name must have appeared in a USE statement within the same scoping unit.

A PRIVATE attribute can be specified on the TYPE statement of a derived-type definition in a module. This specifies the derived-type definition is not accessible outside the module or the module's descendants.

A PRIVATE statement without an entity-list can appear in the component-definition part of a derived-type definition, specifying the default accessibility of all components as PRIVATE. A PRIVATE statement with no entity-list can appear in the type-bound-procedure-part of a derived-type definition specifying the default accessibility of all type-bound procedures of that type as PRIVATE. In such cases, the default accessibility of components and type-bound procedures can be overridden by explicitly declaring a component or type-bound procedure PUBLIC.

A PRIVATE attribute can be specified in the statement declaring a component or a type-bound procedure of a derived type. This specifies that the component or type-bound procedure is not accessible outside the module or its descendants.

If no PRIVATE statements are specified in a module, the default is PUBLIC accessibility. Entities with PUBLIC accessibility can be accessed from outside the module by means of a USE statement.

If a derived type is declared PRIVATE in a module, its components are also PRIVATE. The derived type and its components are accessible to any subprograms within the defining module and the module's descendants through host association, but they are not accessible from outside the module.

If the derived type is declared PUBLIC in a module, but its components are declared PRIVATE, any scoping unit accessing the module though use association (or host association) can access the derived-type definition, but not its components.

If a module procedure has a dummy argument or a function result of a type that has PRIVATE accessibility, the module procedure must have PRIVATE accessibility. If the module has a generic identifier, it must also be declared PRIVATE.

If a procedure has a generic identifier, the accessibility of the procedure's specific name is independent of the accessibility of its generic identifier. One can be declared PRIVATE and the other PUBLIC.

The accessibility of the components of a type is independent of the accessibility of the type name. The following combinations are possible:

  • A private type name with a private component

  • A public type name with a public component

  • A private type name with a public component

  • A public type name with a private component

The accessibility of a type does not affect, and is not affected by, the accessibility of its components and type-bound procedures. If a type definition is private, then the type name, and thus the structure constructor for the type, are accessible only within the module containing the definition.

Example

The following examples show type declaration statements specifying the PUBLIC and PRIVATE attributes:

REAL,  PRIVATE  :: A, B, C
INTEGER, PUBLIC :: LOCAL_SUMS

The following is an example of the PUBLIC and PRIVATE statements:

MODULE SOME_DATA
  REAL ALL_B
  PUBLIC ALL_B
  TYPE RESTRICTED_DATA
    REAL LOCAL_C(50)
  END TYPE RESTRICTED_DATA
  PRIVATE RESTRICTED_DATA
END MODULE

The following derived-type declaration statement indicates that the type is restricted to the module:

TYPE, PRIVATE  :: DATA
  ...
END TYPE DATA

The following example shows a PUBLIC type with PUBLIC and PRIVATE components:

MODULE MATTER
  TYPE ELEMENTS
    PRIVATE              ! Sets default accessibility is PRIVATE
    REAL,PUBLIC :: A, B  ! Overrides the default accessibility of PRIVATE
    INTEGER C, D         ! PRIVATE components 
  END TYPE
...
END MODULE MATTER

In this case, components A and B are PUBLIC, components C and D are private to type ELEMENTS, but type ELEMENTS is not private to MODULE MATTER. Any program unit that uses the module MATTER, can declare variables of type ELEMENTS and access components A and B.

Variables of type ELEMENTS can be passed to module procedures defined in module MATTER, where component C and D are accessible. They are not accessible outside of module MATTER.

The following shows another example:

 !LENGTH in module VECTRLEN calculates the length of a 2-D vector.
 !The module contains both private and public procedures
    MODULE VECTRLEN
      PRIVATE SQUARE
      PUBLIC LENGTH
     CONTAINS
     SUBROUTINE LENGTH(x,y,z)
        REAL,INTENT(IN) x,y
        REAL,INTENT(OUT) z
        CALL SQUARE(x,y)
        z = SQRT(x + y)
        RETURN
     END SUBROUTINE
     SUBROUTINE SQUARE(x1,y1)
        REAL x1,y1
        x1 = x1**2
        y1 = y1**2
        RETURN
     END SUBROUTINE
    END MODULE