| Fortran Language Reference Manual, Volume 1 - S-3692-51 | ||
|---|---|---|
| Prev Section | Chapter 5. Declarations | Next Section |
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.
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:
|
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 |
| |
| is |
| ||
|
| or |
| |
| access_id | is |
| |
|
| or |
|
Specify one of the following for generic_spec:
generic_name
OPERATOR (defined_operator)
ASSIGNMENT (=)
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 |
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:
|
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.
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:
ALLOCATABLE
DIMENSION
POINTER
PUBLIC
PRIVATE
SAVE
TARGET
VOLATILE
VALUE
BIND(C)
STATIC
AUTOMATIC
The PROTECTED attribute and statement have these restrictions:
Only a module's specification part can use the PROTECTED attribute and statement.
Only procedures within the module that defines the PROTECTED variable can modify the variable. Programs that access protected variables by USE association cannot modify the variable.
Variables using the PROTECTED attribute cannot use the EXTERNAL, INTRINSIC, or PARAMETER attribute.
COMMON blocks cannot have PROTECTED variables as members.
All variables within a module are protected when the PROTECTED statement does not have an access_id list.
Only PROTECTED variables can be equivalenced to other PROTECTED variables
When passing a PROTECTED variable to a procedure that has an explicit interface, the associated dummy argument must have the INTENT(IN) attribute.
A nonpointer object that has the PROTECTED attribute and is accessed through use association cannot not appear in a variable definition context or cannot appear on the right-hand side of a pointer assignment statement as a data target.
A pointer object that has the PROTECTED attribute and is accessed by use association cannot appear as one of the following:
A pointer_object in a pointer_assignment_stmt or nullify_stmt
An allocate_object in an allocate_stmt or deallocate_stmt
An actual argument in a reference to a procedure if the associated dummy argument is a pointer that has the INTENT(OUT) or INTENT(INOUT) attribute
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 |
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_spec | is |
| |
|
| or |
| |
|
| or |
|
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 |
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:
PARAMETER
EXTERNAL
POINTER
ALLOCATABLE
DIMENSION
VOLATILE (F2003)
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.
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 |
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.
| is |
| ||
| bind_spec | is |
| |
| scalar_char_initialization_expr | is |
|
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:
AUTOMATIC (EXTENSION)
POINTER
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 |
| |
| bind_entity | is | object_name | |
|
| or |
|
Here are some guidelines for using the BIND statements:
BIND statements that have an object_name can only appear in the specification part of a module.
If you use the bind_spec_list (that is use the NAME specifier), specify only one Fortran variable name in bind_entity_list.
If a C name is the same as the bind_entity name (with the exception of case), you can omit the bind_spec_list, because the compiler will automatically generate an all lower case C name from the bind_entity name. Here is an example to illustrate this:
BIND(C) :: C_VAR !Bind C_VAR to extern C variable c_var |
Only one Fortran variable can be bound to a C variable.
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.
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:
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
. . . |
| Prev Section | Table of Contents | Title Page | Index | Next Section |
| Data Initialization and the DATA Statement | Up one level | Procedure Properties |