Chapter 5. Declarations

Table of Contents
5.1. Type Declaration Statements
5.2. Implicit Typing
5.3. Array Properties
5.4. POINTER Properties
5.5. Data Initialization and the DATA Statement
5.6. Object Accessibility and Use
5.7. Procedure Properties
5.8. Automatic Data Objects
5.9. AUTOMATIC Attribute and Statement (EXTENSION)
5.10. ALLOCATABLE Attribute and Statement
5.11. SAVE and STATIC Attributes and Statements
5.12. VOLATILE Attribute and Statement
5.13. NAMELIST Statement
5.14. Storage Association

Declarations are used to specify the type and other attributes of program entities. The attributes that an entity possesses determine how the entity can be used in a program. Every variable and function has a type, which is the most important of the attributes; type is discussed in Chapter 4. However, type is only one of a number of attributes that an entity may possess. Some entities, such as subroutines and namelist groups, do not have a type but may possess other attributes. In addition, there are relationships among objects that can be specified by EQUIVALENCE, COMMON, and NAMELIST statements. Declarations are used to specify these attributes and relationships.

Generally, Fortran keywords are used to declare the attributes for an entity. The following list summarizes these keywords:

Attribute 

Keyword

Type 

INTEGER, REAL (and DOUBLE PRECISION), COMPLEX, LOGICAL, CHARACTER, TYPE (user-defined name), TYPEALIAS

Array properties 

DIMENSION, ALLOCATABLE

Pointer properties 

POINTER, TARGET

Setting values 

DATA, PARAMETER

Object accessibility and use 

PUBLIC, PROTECTED, PRIVATE, INTENT, OPTIONAL, BIND, VALUE

Procedure properties 

EXTERNAL, INTRINSIC

Storage 

ALLOCATABLE, AUTOMATIC, SAVE, STATIC, VOLATILE

Note: The Fortran standard does not describe AUTOMATIC, or STATIC attribute. BIND, PROTECTED, VALUE, and VOLATILE are Fortran 2003 features.

The attributes are described and illustrated in turn using either of the two forms that attribute specifications can take: entity-oriented and attribute-oriented.

For objects that have a type, other attributes can be included in the type declaration statement. For example:

INTEGER, SAVE :: A, B, C

Collecting the attributes into a single statement is sometimes more convenient for readers of programs. It eliminates searching through many declaration statements to locate all attributes of a particular object. Emphasis can be placed on an object and its attributes (entity-oriented declaration) or on an attribute and the objects that possess the attribute (attribute-oriented declaration), whichever is preferred by a programmer. In both forms, dimensionality can be specified as an attribute or as an attachment to the object name.

The following are examples of entity-oriented declaration statements:

REAL, DIMENSION(20), SAVE :: X

or

REAL, SAVE :: X(20)

The following are examples of attribute-oriented declaration statements:

REAL X
DIMENSION X(20)
SAVE X

or

REAL X(20)
SAVE X

If attributes are not declared for a data object, defaults apply. Generally, if an attribute is not specified for an object, it is assumed that the object does not possess the attribute. However, each data object has a type, and if this is not explicitly specified, it is assumed from the first letter of its name. You can use the IMPLICIT statement to specify any intrinsic or user-defined type for an initial letter or a range of initial letters. The IMPLICIT NONE statement, on the other hand, removes implicit typing and thus requires explicit type declarations for every named data object in the scoping unit.

Fortran provides dynamic data objects that can be sized at the time a program is executed. These include allocatable objects and objects with the POINTER attribute. They also include automatic data objects (arrays of any type and character strings) that are created on entry into a procedure. Only objects whose size may vary are called automatic.

Other declarations (NAMELIST, EQUIVALENCE, and COMMON) establish relationships among data objects. The NAMELIST statement is used to name a collection of objects so that they can be referenced by a single name in an input/output (I/O) statement. EQUIVALENCE provides references to storage by more than one name. COMMON provides a mechanism to share storage among the different units of a program.

5.1. Type Declaration Statements

A type declaration type statement begins with the name of the type, optionally lists other attributes, then ends with a list of variables that possess these attributes. In addition, a type declaration statement may include an initial value for a variable. If the PARAMETER attribute is specified on a type statement, the statement must include the value of the named constant.

The type_declaration_stmt is defined as follows:

Table 5-1.

 

type_declaration_stmt

is

type_spec [[, attr_spec]... :: ] entity_decl_list

 

type_spec

is

INTEGER  kind_selector

 

 

or

REAL  kind_selector

 

 

or

DOUBLE PRECISION

 

 

or

COMPLEX  kind_selector

 

 

or

CHARACTER  char_selector

 

 

or

LOGICAL  kind_selector

 

 

or

TYPE ( type_name)

 

 

or

TYPE ( type_alias_name)

EXT

 

or

INTEGER*  length_value

EXT

 

or

REAL*  length_value

EXT

 

or

DOUBLE PRECISION*  length_value

EXT

 

or

COMPLEX*  length_value

EXT

 

or

LOGICAL*  length_value

EXT

 

or

POINTER ( pointer_name, pointee_name [ (array_spec) ])

 

attr_spec

is

PARAMETER

 

 

or

access_spec

 

 

or

ALLOCATABLE

 

 

or

DIMENSION ( array_spec)

 

 

or

EXTERNAL

 

 

or

INTENT ( intent_spec)

 

 

or

INTRINSIC

F2003

 

or

language_binding_spec

 

 

or

OPTIONAL

 

 

or

POINTER

F2003

 

or

PROTECTED

 

 

or

SAVE

 

 

or

TARGET

F2003

 

or

VALUE

F2003

 

or

VOLATILE

EXT

 

or

AUTOMATIC

EXT

 

or

STATIC

 

access_spec

is

PUBLIC

 

 

or

PRIVATE

 

entity_decl

is

object_name [(array_spec) ] [ * char_length ] [ initialization ]

 

 

or

function_name [ * char_length ]

 

kind_selector

is

([ KIND=] scalar_int_initialization_expr)

 

initialization

is

=intialization_expr

 

 

or

=>NULL()

The double colon symbol (::) is required in a type declaration statement only when the type declaration statement contains two or more attributes or when it contains an initialization_expr.

See Section 7.2.9.2 for more information about valid values for initialization.

If => appears in initialization, the object must have the POINTER attribute. If = appears in initialization, the object cannot have the POINTER attribute.

The type specification can override or confirm the implicit type indicated by the first letter of the entity name according to the implicit typing rules in effect.

The same attribute can appear more than once in a given type declaration statement.

Note: The Fortran standard permits an attribute to appear only once in a given type declaration. The Cray Fortran Compiler relaxes this restriction.

The value specified in a kind selector must be a kind type parameter allowed for that type by the Cray Fortran Compiler.

The character length option can appear only when the type specification is CHARACTER.

An initialization expression must be included if the PARAMETER attribute is specified.

A function name must be the name of an external function, an intrinsic function, a function dummy procedure, or a statement function.

An array function result name must be specified as an explicit-shape array unless it has the POINTER or ALLOCATABLE attribute, in which case it must be specified as a deferred-shape array. For information on array properties, see Section 5.3.

Other rules and restrictions pertain to particular attributes; these are covered in the sections describing those attributes. The attributes that can be used with the attribute being described are also listed. The simple forms that appear in the following sections to illustrate attribute specification in a type declaration statement show the attribute being described first in the attribute list, but attributes can appear in any order. If these simple forms are used to construct statements, the statements will be correct, but other variations are permitted.

The following examples show type declaration statements:

REAL A(10)
LOGICAL, DIMENSION(5,5) :: MASK_1, MASK_2
COMPLEX :: CUBE_ROOT = (-0.5, 0.867)
INTEGER, PARAMETER :: SHORT = SELECTED_INT_KIND(4)
INTEGER(SHORT) :: K           ! Range of -9999 to 9999
REAL, ALLOCATABLE :: A1(:, :), A2(:, :, :)
REAL, ALLOCATABLE :: A3       ! Allocatable scalar
TYPE(PERSON) CHAIRMAN
TYPE(NODE), POINTER :: HEAD_OF_CHAIN, END_OF_CHAIN
REAL, INTENT(IN) :: ARG1
REAL, INTRINSIC :: SIN
REAL, POINTER, DIMENSION (:) :: S => NULL()

5.1.1. Integer

An INTEGER statement declares the names of entities to be of type integer. If a kind selector is present, it specifies the representation method. For more information on integer type, see Section 4.3.1.

The Cray Fortran Compiler supports the following formats for declaring objects of this type:

INTEGER [ ([ KIND
= ] kind_param) ] [[ , attribute_list ] :: ]  entity_list

INTEGER * length_value [ [ , attribute_list ] :: ] entity_list

For kind_param values, see Section 4.3.1. The length_value values correspond to the kind_param values. The values are 1, 2, 4 (default), and 8.

The following are examples of entity-oriented declaration statements:

INTEGER, DIMENSION(:), POINTER :: MILES, HOURS
INTEGER(SHORT), POINTER :: RATE, INDEX

The following are examples of attribute-oriented declaration statements:

INTEGER :: MILES, HOURS
INTEGER(SHORT) :: RATE, INDEX
DIMENSION :: MILES(:), HOURS(:)
POINTER :: MILES, HOURS, RATE, INDEX

Note: The Fortran standard does not specify the INTEGER*length_value syntax. It is recommended that this syntax not be used in any new code.

5.1.2. Real

A REAL statement declares the names of entities to be of type real. If a kind selector is present, it specifies the representation method. For more information on real type, see Section 4.3.2.

The Cray Fortran Compiler supports the following formats for declaring objects of this type:

REAL [ ([ KIND = ] kind_param) ] [ [ , attribute_list ] :: ]  entity_list

REAL * length_value [ [ , attribute_list ] :: ] entity_list

For kind_param values, see Section 4.3.2. The length_value values correspond to the kind_param values and are as follows:

  • The values are as follows: 4 (default), 8, and 16.

The following examples show entity-oriented declaration statements:

REAL(KIND = HIGH), OPTIONAL :: VARIANCE
REAL, SAVE :: A1(10, 10), A2(100, 10, 10)

The following examples show attribute-oriented declaration statements:

REAL(KIND = HIGH) VARIANCE
REAL A1(10, 10), A2(100, 10, 10)
OPTIONAL VARIANCE
SAVE A1, A2

Note: The Fortran standard does not specify the REAL *length_value syntax. It is recommended that this syntax not be used in any new code.

5.1.3. Double Precision

A DOUBLE PRECISION statement declares the names of entities to be of real type with a representation method that represents more precision than the default real representation. A kind selector is not permitted in the DOUBLE PRECISION statement. For more information on the real data type, see Section 4.3.2.

The Cray Fortran Compiler supports the following formats for declaring objects of this type:

DOUBLE PRECISION [ [ , attribute_list ] :: ] entity_list

DOUBLE PRECISION * 16 [ [, attribute_list ] :: ] entity_list

The following examples show entity-oriented declaration statements:

DOUBLE PRECISION, DIMENSION(N,N) :: MATRIX_A, MATRIX_B
DOUBLE PRECISION, POINTER :: C, D, E, F(:, :)

The following examples show attribute-oriented declaration statements:

DOUBLE PRECISION :: MATRIX_A, MATRIX_B, C, D, E, F
DIMENSION :: MATRIX_A(N, N), MATRIX_B(N, N), F(:, :)
POINTER :: C, D, E, F

If DOUBLE is a named integer constant that has the value of the kind parameter of the double-precision real type on the target platform, the preceding entity-oriented declaration statements could be written as follows:

REAL (DOUBLE), DIMENSION (N,N) :: MATRIX_A, MATRIX_B
REAL (DOUBLE), POINTER :: C, D, E, F(:,:)

Note: The Fortran standard does not specify the DOUBLE PRECISION*16 syntax. It is recommended that this syntax not be used in any new code.

5.1.4. Complex

A COMPLEX statement declares the names of entities to be of type complex. If a kind selector is present, it specifies the representation method. For more information on complex type, see Section 4.3.3.

The Cray Fortran Compiler supports the following formats for declaring objects of this type:

COMPLEX [([ KIND
= ] kind_param)] [ [ , attribute_list ] :: ] entity_list

COMPLEX * length_value [ [, attribute_list ] :: ] entity_list

For kind_param values, see Section 4.3.3. The length_value values correspond to the kind_param values in the following manner:

  • The values are as follows:

    kind_param 

    length_value

    4 

    8

    8 (default) 

    16 (default)

    16 

    32

The following examples show entity-oriented declaration statements:

COMPLEX(KIND = LOW), POINTER :: ROOTS(:)
COMPLEX, POINTER :: DISCRIMINANT, COEFFICIENTS(:)

The following examples show attribute-oriented declaration statements:

COMPLEX(KIND = LOW) :: ROOTS(:)
COMPLEX :: DISCRIMINANT, COEFFICIENTS(:)
POINTER :: ROOTS, DISCRIMINANT, COEFFICIENTS

Note: The Fortran standard does not specify the COMPLEX*length_value syntax. It is recommended that this syntax not be used in any new code.

5.1.5. Logical

A LOGICAL statement declares the names of entities to be of type logical. If a kind selector is present, it specifies the representation method. For more information on logical type, see Section 4.3.4.

The Cray Fortran Compiler supports the following formats for declaring objects of this type:

LOGICAL [ ([ KIND = ] kind_param)] [ [, attribute_list ] :: ]  entity_list

LOGICAL * length_value [ [, attribute_list ] :: ] entity_list

For kind_param values, see Section 4.3.4. The length_value values correspond to the kind_param values in the following manner:

kind_param 

length_value

1 

1

2 

2

4 (default) 

4 (default)

8 

8

The following examples show entity-oriented declaration statements:

LOGICAL, ALLOCATABLE :: MASK_1(:), MASK_2(:)
LOGICAL(KIND = WORD), SAVE :: INDICATOR, STATUS

The following examples show attribute-oriented declaration statements:

LOGICAL MASK_1(:), MASK_2(:)
LOGICAL (KIND = WORD) INDICATOR, STATUS
ALLOCATABLE MASK_1, MASK_2
SAVE INDICATOR, STATUS

Note: The Fortran standard does not specify the LOGICAL*length_value syntax. It is recommended that this syntax not be used in any new code.

5.1.6. Character

A CHARACTER statement declares the names of entities to be of type character. For more information on character type, see Section 4.3.5.

The following is a format for declaring objects of this type:

CHARACTER [ char_selector ] [ [ , attribute_list ] :: ] entity_list

The components of this format are defined as follows:

Table 5-2.

 

char_selector

is

length_selector

 

 

or

(LEN =  char_len_param_value, KIND = kind_value) 

 

 

or

( char_len_param_value, [ KIND = ]  kind_value)

 

 

or

(KIND =  kind_value [, LEN = char_len_param_value  ])

 

length_selector

is

([ LEN = ] char_len_param_value)

OBS

 

or

* char_length [ , ]

 

char_length

is

(char_len_param_value)

 

 

or

scalar_int_literal_constant

 

char_len_param_value

is

specification_expr

 

 

or

*

 

kind_value

is

scalar_int = initialization_expr

The optional comma in a length_selector is permitted only if no double colon separator appears in the type declaration statement.

A character type declaration can specify a character length that is a nonconstant expression if it appears in a procedure or a procedure interface and if it is not a component declaration in a derived-type definition or type alias statement. The length is determined on entry into the procedure and is not affected by any changes in the values of variables in the expression during the execution of the procedure. A character object declared this way that is not a dummy argument is called an automatic data object.

The length of a named character entity or a character component in a type definition is specified by the character selector in the type specification unless there is a character length in an entity or component declaration; if so, the character length specifies an individual length and overrides the length in the character selector. If a length is not specified in either a character selector or a character length, the length is 1.

If the length parameter has a negative value, the length of the character entity is 0.

If a scalar integer literal constant is used to specify a character length, it must not include a kind parameter. (This could produce an ambiguity when fixed source form is used.)

A length parameter value of * can be used only in the following ways:

  • To declare a dummy argument of a procedure, in which case the dummy argument assumes the length of the associated actual argument when the procedure is invoked.

  • To declare a named constant, in which case the length is that of the constant value.

  • To declare the result variable for an external function. Any scoping unit that invokes the function must declare the function with a length other than *, or it must access such a declaration by host or use association. When the function is invoked, the length of the result is the value specified in the declaration in the program unit referencing the function. Note that an implication of this rule is that a length of * must not appear in an IMPLICIT statement.

  • To declare a character pointee.

A function name must not be declared with a length of * if the function is an internal or module function; or if it is array-valued, pointer-valued, or recursive; or if it is a PURE function.

An interface body can be specified for a dummy or external function whose result is of type CHAR*(*) only if the function is not invoked. This is because the characteristics must match in both places.

The length of a character-valued statement function or statement function dummy argument of type character must be an integer constant expression.

The following examples show entity-oriented character type declaration statements:

CHARACTER(LEN = 10, KIND = ASCII), SAVE :: GREETING(2)
CHARACTER(10) :: PROMPT = "PASSWORD?"
CHARACTER(*), INTENT(IN) :: HOME_TEAM, VISITORS
CHARACTER*(3), SAVE :: NORMAL_1, LONGER(9)*20, NORMAL_2
CHARACTER :: GRADE = "A"

The following examples show attribute-oriented character type declaration statements:

CHARACTER(LEN = 10, KIND = ASCII) :: GREETING
CHARACTER(10) :: PROMPT
CHARACTER(*) :: HOME_TEAM, VISITORS
CHARACTER*(3) :: NORMAL_1, LONGER*20, NORMAL_2
CHARACTER GRADE
SAVE :: GREETING, NORMAL_1, LONGER, NORMAL_2
DIMENSION GREETING(2), LONGER(9)
INTENT(IN) :: HOME_TEAM, VISITORS
DATA PROMPT / "PASSWORD?" /, GRADE / "A" /

5.1.7. Derived Type

A TYPE declaration statement declares the names of entities to be of the specified user-defined type. The type name appears in parentheses following the keyword TYPE. For more information on derived types, see Section 4.4.

The following is a format for declaring objects of user-defined type:

TYPE (type_name) [ [ , attribute_list ] :: ] entity_list

The following examples show entity-oriented derived type declaration statements:

TYPE(COLOR), DIMENSION(:), ALLOCATABLE :: HUES_OF_RED
TYPE(PERSON), SAVE :: CAR_POOL(3)
TYPE(PARAGRAPH), SAVE :: OVERVIEW, SUBSTANCE, SUMMARY

The following examples show attribute-oriented derived type declaration statements:

TYPE(COLOR) :: HUES_OF_RED
TYPE(PERSON) :: CAR_POOL(3)
TYPE(PARAGRAPH) :: OVERVIEW, SUBSTANCE, SUMMARY
DIMENSION :: HUES_OF_RED(:)
ALLOCATABLE :: HUES_OF_RED
SAVE :: CAR_POOL, OVERVIEW, SUBSTANCE, SUMMARY

An object of derived type (a structure) must not have the PUBLIC attribute if its type is private.

A structure constructor must be used to initialize an object of derived type. Each component of the structure constructor must be an initialization expression. For more information on structure constructors, see Section 4.7.

Note: Variables declared to be Cray pointers and pointees through the Cray POINTER statement cannot be declared as components of derived types.

5.1.8. Cray Pointer (EXTENSION)

The Cray POINTER statement declares one variable to be a Cray pointer (that is, to have the Cray pointer data type) and another variable to be its pointee; that is, the value of the Cray pointer is the address of the pointee. This statement has the following format:

POINTER (pointer_name,  pointee_name [ (array_spec) ])
   [, (pointer_name, pointee_name [ (array_spec) ]) ] ...

pointer_name 

Pointer to the corresponding pointee_name. pointer_name contains the address of pointee_name. Only a scalar variable can be declared type Cray pointer; constants, arrays, statement functions, and external functions cannot.

pointee_name 

Pointee of corresponding pointer_name. Must be a variable name, array declarator, or array name. The value of pointer_name is used as the address for any reference to pointee_name; therefore, pointee_name is not assigned storage. If pointee_name is an array declarator, it can be explicit-shape (with either constant or nonconstant bounds) or assumed-size.

array_spec 

If present, this must be either an explicit_shape_spec_list, with either constant or nonconstant bounds) or an assumed_size_spec.

Example:

POINTER(P,B),(Q,C)

This statement declares Cray pointer P and its pointee B, and Cray pointer Q and pointee C; the pointer's current value is used as the address of the pointee whenever the pointee is referenced.

An array that is named as a pointee in a Cray POINTER statement is a pointee array. Its array declarator can appear in a separate type or DIMENSION statement or in the pointer list itself. In a subprogram, the dimension declarator can contain references to variables in a common block or to dummy arguments. As with nonconstant bound array arguments to subprograms, the size of each dimension is evaluated on entrance to the subprogram, not when the pointee is referenced. For example:

POINTER(IX, X(N,0:M))

Note: The Fortran standard does not specify the Cray POINTER statement or data type. Variables declared to be pointers and pointees through the Cray POINTER statement cannot be declared as components of derived types.

In addition, pointees must not be deferred-shape or assumed-shape arrays. An assumed-size pointee array is not allowed in a main program unit.

5.1.9. Cray Character Pointer (EXTENSION)

To define a character pointer, use the CLOC(3i) intrinsic function. (The LOC(3i) intrinsic function returns only the word address.)

The FCD(3i) function can also be used to construct a Cray character pointer. FCD(3i) has two integer arguments:

  • The first argument is the word address for the first character of the pointee.

  • The second argument is the character length of the pointee.

If the pointee does not begin on a word boundary, the character offset can be added to the FCD(3i) result.

Note: Intrinsic functions CLOC(3i) and FCD(3i) are not part of the Fortran standard.

The size of a Fortran Character Descriptor (FCD) and of a Cray character pointer depends on your platform, so Cray character pointers should not be equivalenced or storage-associated. For more information on FCDs, see FCD(3i).

Example:

CPTR = FCD(IADRS,ILEN) + IOFFSET

Cray character pointers are not optimized. Statements containing them are not vectorized or Autotasked.

The following operations are the only ones allowed with Cray character pointers, where cp is a character pointer and i is an integer. Arithmetic is in bytes (characters), not words or bits:

  • cp + i

  • cp - i

  • i + cp

  • cp = cp

  • cp relational_operator cp