5.6. Object Accessibility and Use

Several attributes indicate where an object can be accessed and how it can be used. Some of these attributes apply only to objects in a module and others apply only to dummy arguments or other variables that are declared in a subprogram.

5.6.1. PUBLIC and PRIVATE Attributes and Statements

The PUBLIC, and PRIVATE attributes control access to type definitions, variables, functions, and named constants in a module. The PUBLIC attribute declares that entities in a module are available outside the module by use association; the PRIVATE attribute prevents access outside the module by use association. The default accessibility is PUBLIC, but it can be changed to PRIVATE.

The following formats are for type declaration statements with PUBLIC and PRIVATE attributes:

type, PUBLIC [, attribute_list ] :: entity_decl_list

type, PRIVATE [, attribute_list ] :: entity_decl_list

Subject to the rules governing combinations of these attributes, attribute_list can contain the following:

ALLOCATABLE
BIND (F2003)
DIMENSION
EXTERNAL
INTRINSIC
PARAMETER
POINTER
PROTECTED (F2003)
SAVE
STATIC (EXTENSION)
TARGET
VOLATILE (F2003)

The type declaration statement can also contain an initialization_expr.

PUBLIC and PRIVATE statements provide another means for controlling the accessibility of variables, functions, type definitions, and named constants. PUBLIC and PRIVATE statements can control the accessibility of some entities that do not have a type; these are subroutines, generic specifiers, and namelist groups. The formats for PUBLIC and PRIVATE statements are defined as follows:

Table 5-14.

 

access_stmt

is

access_spec [ [ :: ] access_id_list ]

 

access_spec

is

PUBLIC

 

 

or

PRIVATE

 

access_id

is

use_name

 

 

or

generic_spec

Specify one of the following for generic_spec:

PUBLIC, and PRIVATE statements can appear only in a module.

The PUBLIC and PRIVATE statements also confer the PUBLIC or PRIVATE attribute. They are subject to the same rules and restrictions as the PUBLIC and PRIVATE attributes.

A use_name can be the name of a variable, procedure, derived type, type alias, named constant, or namelist group.

Generic specifications are explained further in the Fortran Language Reference Manual, Volume 2. The following are examples of PUBLIC and PRIVATE statements that might be used with generic specifications:

PUBLIC HYPERBOLIC_COS, HYPERBOLIC_SIN     ! generic names
PRIVATE MY_COS_RAT, MY_SIN_RAT            ! specific names
PRIVATE MY_COS_INF_PREC, MY_SIN_INF_PREC  ! specific names
PUBLIC :: OPERATOR ( .MYOP. ), OPERATOR (+), ASSIGNMENT (=)

Only one PUBLIC or PRIVATE statement with an omitted access_id list is permitted in the scoping unit of a module. It determines the default accessibility of the module.

The default accessibility of entities defined in a module is PUBLIC. A PUBLIC statement without an access_id list can appear in the module to confirm the default accessibility. A PRIVATE statement without an access_id list can appear in the module to change the default accessibility.

A procedure that has a generic identifier that is public is accessible through the generic identifier even if its specific name is private. The converse is also true. That is, a module procedure that is public, but whose generic identifier is private, is still accessible through its specific name.

A module procedure that has an argument of a private type or a function result of a private type must be private and must not have a generic identifier that is public.

The following examples show entity-oriented declarations:

REAL, PUBLIC :: GLOBAL_X
TYPE, PRIVATE :: LOCAL_DATA
   LOGICAL :: FLAG
   REAL, DIMENSION(100) :: DENSITY
END TYPE LOCAL_DATA

The following examples show attribute-oriented declarations:

REAL GLOBAL_X
PUBLIC GLOBAL_X
TYPE LOCAL_DATA
   LOGICAL FLAG
   REAL DENSITY
   DIMENSION DENSITY(100)
END TYPE LOCAL_DATA
PRIVATE LOCAL_DATA

The following example shows a public type declaration with private components:

TYPE LIST_ELEMENT
   PRIVATE
   REAL VALUE
   TYPE(LIST_ELEMENT), POINTER :: NEXT, FORMER
END TYPE LIST_ELEMENT

The following example shows how to override the default accessibility:

MODULE M
   PRIVATE
   REAL R, K, TEMP(100)           ! R, K, and TEMP are private
   REAL, PUBLIC :: A(100), B(100) ! A and B are public
END MODULE M

5.6.1.1. Using PUBLIC and PRIVATE with Derived Types

The PUBLIC and PRIVATE attributes can also define the accessibility of a derived type and of each of its components. The accessibility of a component is independent of the accessibility of the type. Therefore, it is possible to also have mixed accessibility attributes within a derived type as shown below:

  • A public type with public and/or private components

  • A private type with public and/or private components

Public types and components are accessible through use association. Private types and components are accessible only within the module that defines it. However, if a private type has a public component, the component is accessible through use association.

The following shows the derived type statements and component definition statements:

TYPE, PUBLIC :: type_name

TYPE, PRIVATE :: type_name

type_spec, PUBLIC :; component_name

type_spec, PRIVATE :; component_name

The following shows a derived type with mix accessibility attributes:

TYPE MIXED
    PRIVATE
    INTEGER :: I
    INTEGER, PUBLIC :: J
END TYPE MIXED

TYPE (MIXED) :: M

The M%J component is accessible in any scoping unit where M is accessible; component M%I is accessible only within the module containing the TYPE MIXED definition.

For more information about derived-type definitions, see Section 4.4.1.

5.6.2. PROTECTED Attribute and Statement

The PROTECTED attribute protects a variable from modification by objects outside of a module. That is, the variable is read only. This is the format of the PROTECTED statement:

type, PROTECTED [, attribute_list ] :: decl_list

Note: The PROTECTED attribute and statement are Fortran 2003 features.

The attribute_list can contain the following attributes:

The PROTECTED attribute and statement have these restrictions:

The example below shows how to use the PROTECTED statement:

MODULE M
INTEGER,PROTECTED :: A
INTEGER :: C
END MODULE

PROGRAM PROG
USE M
X = A !Okay to read PROTECTED variable
A = X !Error, A is protected
END PROGRAM

5.6.3. INTENT Attribute and Statement

The INTENT attribute specifies the intended use of a dummy argument. If specified, it can help detect errors, provide information for readers of the program, and give the compiler information that can be used to make the code more efficient. It is particularly valuable in creating software libraries.

Some dummy arguments are referenced but not redefined within the subprogram; some are defined before being referenced within the subprogram; others can be referenced before being redefined. INTENT has three forms: IN, OUT, and INOUT, which correspond respectively to the preceding three situations.

If the intent of an argument is IN, the subprogram must neither change the value of the argument nor must the argument become undefined during the course of the subprogram. If the intent is OUT, the subprogram must not use the argument before it is defined, and it must be definable. If the intent is INOUT, the argument can be used to communicate information to the subprogram and return information; it must be definable. If no intent is specified, the use of the argument is subject to the limitations of the associated actual argument. For example, the actual argument may be a constant (for example, 2) or a more complicated expression (for example, N+2), and in these cases the dummy argument can be referenced but not defined.

The following is a format for a type declaration statement with an INTENT attribute:

type, INTENT (intent_spec) [, attribute_list ] :: decl_list

For intent_spec, specify one of the following arguments:

IN
OUT
INOUT

The attribute_list can contain the following attributes:

ALLOCATABLE
DIMENSION
OPTIONAL
POINTER
TARGET
VOLATILE (F2003)

The INTENT statement also provides a means of specifying an intent for an argument. Its format is defined as follows:

Table 5-15.

 

intent_stmt

is

INTENT ( intent_spec) [ :: ] dummy_arg_name_list 

 

intent_spec

is

IN

 

 

or

OUT

 

 

or

INOUT

The INTENT attribute can be specified only for dummy arguments.

An INTENT statement can appear only in the specification part of a subprogram or interface body.

An intent must not be specified for a dummy argument that is a dummy procedure because it is not possible to change the definition of a procedure. Intent for a dummy pointer must not be specified either.

The INTENT statement also confers the INTENT attribute. It is subject to the same rules and restrictions as the INTENT attribute.

If an argument is of a type that is default initialized when it is declared with INTENT(OUT), the components that are initialized are defined when the procedure is invoked.

An assumed-size array with INTENT(OUT) cannot be a type for which default initialization is specified.

The following examples show entity-oriented declarations:

SUBROUTINE MOVE(FROM, TO)
   USE PERSON_MODULE
   TYPE(PERSON), INTENT(IN) :: FROM
   TYPE(PERSON), INTENT(OUT) :: TO

SUBROUTINE SUB(X, Y)
   INTEGER, INTENT(INOUT) :: X, Y

The following examples show attribute-oriented declarations:

SUBROUTINE MOVE(FROM, TO)
   USE PERSON_MODULE
   TYPE(PERSON) FROM, TO
   INTENT(IN) FROM
   INTENT(OUT) TO

SUBROUTINE SUB(X, Y)
   INTEGER X, Y
   INTENT(INOUT) X, Y

5.6.4. VALUE Attribute and Statement

The VALUE attribute specifies that an argument is passed-by-value rather than passed-by-reference. That is, any changes made to the dummy argument by the called program are kept within the called program. Fortran procedures may use this attribute when calling C functions or CAL programs that have arguments that are passed-by-value. Only dummy arguments can use the VALUE attribute.

Note: The VALUE attribute and statement are Fortran 2003 features.

This is the format for a type declaration statement that uses the VALUE attribute:

type, VALUE [ attribute_list ] :: value_name_list

Type character arguments that use the VALUE attribute must not specify the length parameter or must specify a length of one.

Do not use these attributes with the VALUE attribute:

If a dummy argument uses the TARGET and VALUE attributes, all pointers associated with the dummy argument become undefined when the called procedure exits.

A subprogram with dummy arguments that use the VALUE attribute must have an explicit interface if it is called by another subprogram.

The VALUE statement, as shown below, gives a dummy argument the VALUE attribute. The statement is subject to the same rules and restrictions as the VALUE attribute.

Table 5-16.

 

value_stmt

is

VALUE [ :: ] dummy_arg_name_list

Note: The VALUE statement can appear only in the scoping unit of a subprogram or interface body.

The following shows an entity-oriented declaration in a program fragment:

INTEGER, VALUE :: DUMMY_ARG

The following shows an attribute-oriented declaration to be inserted in the preceding program fragment:

INTEGER :: DUMMY_ARG
VALUE :: DUMMY_ARG

5.6.5. BIND Attribute and Statement

BIND links or binds a Fortran variable or Common block to a C variable with external linkage.

Note: BIND attribute and statement are Fortran 2003 features. The standards organizations continue to interpret the Fortran 2003 draft for Cray and for other vendors. To maintain conformance to Fortran 2003, Cray reserves the right to change the behavior of this feature in future releases based upon the outcome of the interpretations.

The BIND attribute can specify the name of a C object to bind to. If any entity in the entity_decl_list is an object name, the BIND attribute may only be specified in the specification part of a module. This is the format of the BIND attribute:

Table 5-17.

 

language_binding_spec

is

BIND (C [,  bind_spec_list ])

 

bind_spec

is

NAME = scalar_char_initialization_expr

 

scalar_char_initialization_expr

is

" character_string  "

character_string can be any legal name and its type is of default character kind. Since a letter's case is important in C, the string you specify must match the case of the C name. All leading and trailing blanks are ignored.

The bind_spec_list specifies the name of a C global variable to bind to.

If the BIND attribute is specified for a variable or COMMON block, it is used to interoperate with a C variable that has external linkage. That is, a C variable that uses the C EXTERN specifier.

All objects that use the BIND attribute are automatically assigned the SAVE attribute. You can also assign it explicitly.

Objects that have the BIND attribute cannot be initialized.

Variables or dummy arguments that have the BIND attribute cannot have these attributes:

The BIND statement

The BIND statement binds a Fortran name to the C name specified by the BIND attribute. Any restrictions that apply to the BIND attribute will also apply to the BIND statement.

This the format of the BIND statement:

Table 5-18.

 

bind_stmt

is

 language_binding_spec  [::] bind_entity_list

 

bind_entity

is

object_name

 

 

or

/ common_block_name  /

Here are some guidelines for using the BIND statements:

Here are the forms used by BIND:

BIND(C, NAME = "c_name_str") :: FORTRAN_OBJECT_NAME
BIND(C) :: FORTRAN_VARIABLE_NAME
BIND(C, NAME = "c_variable_name") :: FORTRAN_VARIABLE_NAME
BIND(C, NAME = "c_variable_name") :: / COMMON_BLOCK_NAME /

The following is an example of an entity-oriented declaration:

!Binding a Fortran variable to a C variable 
!by explicitly naming the C object
MODULE M
   INTEGER, BIND (C, name="c_variable") :: C_VAR
END MODULE

PROGRAM P
   USE M
   C_VAR = 4
END PROGRAM

!Binding a Fortran variable to C variable a_var
!by implicitly naming the C object
MODULE M
   REAL, BIND(C) :: A_VAR
END MODULE

!Binding a C extern variable to a common block
MODULE
   INTEGER, BIND (C, name="blk") :: /C_BLK/
END MODULE

The following is an example of an attribute-oriented declaration:

!Binding a Fortran variable to a C variable
INTEGER C_VAR
BIND (C, name="c_variable") :: C_VAR

!Binding a Fortran variable to C variable a_var
INTEGER A_VAR
BIND(C) :: A_VAR

!Binding a C extern variable to a common block
BIND (C, name="blk") :: /C_BLK/

See the "C Interoperability" section of Fortran Language Reference Manual, Volume 2 for more information about binding to C objects.

5.6.6. OPTIONAL Attribute and Statement

The OPTIONAL attribute allows a procedure reference to omit arguments with this attribute. The PRESENT(3i) intrinsic function can be used to test the presence of an optional argument in a particular invocation and this test can be used to control the subsequent processing in the procedure. If the argument is not present, the subprogram can supply a default value or it can use an algorithm that is not based on the presence of the argument.

The following is a format for a type declaration statement with an OPTIONAL attribute:

type, OPTIONAL [, attribute_list ] :: entity_decl_list

Subject to the rules governing combinations of these attributes, attribute_list can contain the following:

ALLOCATABLE
DIMENSION
EXTERNAL
INTENT
POINTER
TARGET
VALUE (F2003)
VOLATILE (F2003)

The OPTIONAL statement also provides a means for specifying an argument that can be omitted. Its format is defined as follows:

Table 5-19.

 

optional_stmt

is

OPTIONAL [ :: ] dummy_arg_name_list

The OPTIONAL attribute can be specified only for dummy arguments.

An OPTIONAL statement can appear only in the scoping unit of a subprogram or interface body.

The OPTIONAL statement also confers the OPTIONAL attribute. It is subject to the same rules and restrictions as the OPTIONAL attribute.

The following examples show entity-oriented declarations in a program fragment:

CALL SORT_X(X = VECTOR_A)
   . . .
SUBROUTINE SORT_X(X, SIZEX, FAST)
   REAL, INTENT(INOUT) :: X (:)
   INTEGER, INTENT(IN), OPTIONAL :: SIZEX
   LOGICAL, INTENT(IN), OPTIONAL :: FAST
      . . .

   INTEGER TSIZE

      . . .
   IF (PRESENT(SIZEX)) THEN
      TSIZE = SIZEX
   ELSE
      TSIZE = SIZE(X)
   END IF

   IF (.NOT. PRESENT(FAST) .AND. TSIZE > 1000) THEN
      CALL QUICK_SORT(X)
   ELSE
      CALL BUBBLE_SORT(X)
   END IF
      . . .

The following examples show attribute-oriented declarations to be inserted in the same program fragment:

SUBROUTINE SORT_X(X, SIZEX, FAST)
   REAL X(:)
   INTENT(INOUT) X
   INTEGER SIZEX
   LOGICAL FAST
   INTENT(IN) SIZEX, FAST
   OPTIONAL SIZEX, FAST
      . . .
   INTEGER TSIZE
      . . .