Types

The Cray Fortran compiler supports the following additional data types. This preserves compatibility with other vendor's systems.

The Cray Fortran compiler supports the following additional data types. This preserves compatibility with other vendor's systems.
  • Cray pointer
  • Cray character pointer
  • Boolean (or typeless)

    The Cray Fortran compiler also supports the TYPEALIAS statement as a means of creating alternate names for existing types and supports an expanded form of the ENUM statement.

Alternate Form of LOGICAL Constants

The Cray Fortran compiler accepts .T. and .F. as alternate forms of .true. and .false., respectively.

Cray Pointer Type

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. The value of the Cray pointer is the address of the pointee. This POINTER 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, coarrays, 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. A codimension used to indicate a coarray may not appear in array_spec.

Fortran pointers are declared as follows:
POINTER ::  object-name-list

Cray Fortran pointers and Fortran standard pointers cannot be mixed.

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))

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.

Pointers can be used to access user-managed storage by dynamically associating variables and arrays to particular locations in a block of storage. Cray pointers do not provide convenient manipulation of linked lists because, for optimization purposes, it is assumed that no two pointers have the same value. Cray pointers also allow the accessing of absolute memory locations.

The range of a Cray pointer or Cray character pointer depends on the size of memory for the machine in use.

Restrictions on Cray pointers are as follows:
  • A Cray pointer variable should only be used to alias memory locations by using the LOC intrinsic.
  • A Cray pointer cannot be pointed to by another Cray or Fortran pointer; that is, a Cray pointer cannot also be a pointee or a target.
  • A Cray pointer cannot appear in a PARAMETER statement or in a type declaration statement that includes the PARAMETER attribute.
  • A Cray pointer variable cannot be declared to be of any other data type.
  • A Cray character pointer cannot appear in a DATA statement.
  • An array of Cray pointers is not allowed.
  • A Cray pointer cannot be a component of a structure.
Restrictions on Cray pointees are as follows:
  • A Cray pointee cannot appear in a SAVE, STATIC, DATA, EQUIVALENCE, COMMON, AUTOMATIC, or PARAMETER statement or Fortran pointer statement.
  • A Cray pointee cannot be a dummy argument; that is, it cannot appear in a FUNCTION, SUBROUTINE, or ENTRY statement.
  • A function value cannot be a Cray pointee.
  • A Cray pointee cannot be a structure component.
  • An equivalence object cannot be a Cray pointee.

    Cray pointees can be of type character, but their Cray pointers are different from other Cray pointers; the two kinds cannot be mixed in the same expression.

    The Cray pointer is a variable of type Cray pointer and can appear in a COMMON list or be a dummy argument in a subprogram.

    The Cray pointee does not have an address until the value of the Cray pointer is defined; the pointee is stored starting at the location specified by the pointer. Any change in the value of a Cray pointer causes subsequent references to the corresponding pointee to refer to the new location.

Cray pointers can be assigned values in the following ways:
  • A Cray pointer can be set as an absolute address. For example:
    Q = 0
  • Cray pointers can have integer expressions added to or subtracted from them and can be assigned to or from integer variables. For example:
    P = Q + 100

    However, Cray pointers are not integers. For example, assigning a Cray pointer to a real variable is not allowed.

    The (nonstandard) LOC intrinsic function generates the address of a variable and can be used to define a Cray pointer, as follows:
    P = LOC(X)
    The following example uses Cray pointers in the ways just described:
    SUBROUTINE SUB(N)
     INTEGER WORDS
     COMMON POOL(100000), WORDS(1000)
     INTEGER BLK(128), WORD64
     REAL A(1000), B(N), C(100000-N-1000)
     POINTER(PBLK,BLK), (IA,A), (IB,B), &
           (IC,C), (ADDRESS,WORD64)
     ADDRESS = LOC(WORDS) + 64*KIND(WORDS)
     PBLK = LOC(WORDS)
     IA = LOC(POOL)
     IB = IA + 1000*KIND(POOL)
     IC = IB + N*KIND(POOL)

    BLK is an array that is another name for the first 128 words of array WORDS. A is an array of length 1000; it is another name for the first 1000 elements of POOL. B follows A and is of length N. C follows B. A, B, and C are associated with POOL. WORD64 is the same as BLK(65) because BLK(1) is at the initial address of WORDS.

    If a pointee is of a noncharacter data type that is one machine word or longer, the address stored in a pointer is a word address. If the pointee is of type character or of a data type that is less than one word, the address is a byte address. The following example also uses Cray pointers:
    PROGRAM TEST
    REAL X(*), Y(*), Z(*), A(10)
    POINTER (P_X,X)
    POINTER (P_Y,Y)
    POINTER (P_Z,Z)
    INTEGER*8 I,J
    
    !USE LOC INTRINSIC TO SET POINTER MEMORY LOCATIONS
    !*** RECOMMENDED USAGE, AS PORTABLE CRAY POINTERS ***
    P_X = LOC(A(1))
    P_Y = LOC(A(2))
     
    !USE POINTER ARITHMETIC TO DEMONSTRATE COMPILER AND COMPILER
    !FLAG DIFFERENCES
    !*** USAGE NOT RECOMMENDED, HIGHLY NON-PORTABLE ***
    P_Z = P_X + 1
    
    I = P_Y
    J = P_Z
     
    IF ( I .EQ. J ) THEN
       PRINT *, 'NOT A BYTE-ADDRESSABLE MACHINE'
    ELSE
       PRINT *, 'BYTE-ADDRESSABLE MACHINE'
    ENDIF
     
    END
    On Cray systems, this prints the following:
    Byte-addressable machine

    Cray does not recommend the use of pointer arithmetic because it is not portable.

    For purposes of optimization, the compiler assumes that the storage of a pointee is never overlaid on the storage of another variable; that is, it assumes that a pointee is not associated with another variable or array. This kind of association occurs when a Cray pointer has two pointees, or when two Cray pointers are given the same value. Although these practices are sometimes used deliberately (such as for equivalencing arrays), results can differ depending on whether optimization is turned on or off. Be responsible for preventing such association. For example:
    POINTER(P,B), (P,C)
    REAL X, B, C
    P = LOC(X)
    B = 1.0
    C = 2.0
    PRINT *, B

    Because B and C have the same pointer, the assignment of 2.0 to C gives the same value to B; therefore, B will print as 2.0 even though it was assigned 1.0.

    As with a variable in common storage, a pointee, pointer, or argument to a LOC intrinsic function is stored in memory before a call to an external procedure and is read out of memory at its next reference. The variable is also stored before a RETURN or END statement of a subprogram.

Cray Character Pointer Type

If a pointee is declared as a character type, its Cray pointer is a Cray character pointer.

Restrictions for Cray pointers also apply to Cray character pointers. In addition, the following restrictions apply:
  • When included in an I/O statement iolist, a Cray character pointer is treated as an integer.
  • If the length of the pointee is explicitly declared (that is, not of an assumed length), any reference to that pointee uses the explicitly declared length.
  • If a pointee is declared with an assumed length (that is, as CHARACTER(*)), the length of the pointee comes from the associated Cray character pointer.
  • A Cray character pointer can be used in a relational operation only with another Cray character pointer. Such an operation applies only to the character address and bit offset; the length field is not used.

Boolean Type

A Boolean constant represents the literal constant of a single storage unit. There are no Boolean variables or arrays, and there is no Boolean type statement. Binary, octal, and hexadecimal constants are used to represent Boolean values. For more information about Boolean expressions, see Expressions and Assignment.

Alternate Form of ENUM Statement

An enumeration defines the name of a group of related values and the name of each value within the group. The Cray Fortran compiler allows the following additional form for enum_def (enumerations):

enum_def_stmtisENUM, ,BIND(C) :: type_alias_name
orENUM kind_selector :: type_alias_name
  • kind_selector. If it is not specified, the compiler uses the default integer kind.
  • type_alias_name is the name to assign to the group. This name is treated as a type alias name.

TYPEALIAS Statement

A TYPEALIAS statement allows another name to be defined for an intrinsic data type or user-defined data type. Thus, the type alias and the type specification it aliases are interchangeable. Type aliases do not define a new type.

This is the form for type aliases:
type_alias_stmtisTYPEALIAS :: type_alias_list
type_aliasistype_alias_name => type_spec
This example shows how a type alias can define another name for an intrinsic type, a user-defined type, and another type alias:
TYPEALIAS :: INTEGER_64 => INTEGER(KIND = 8), &
             TYPE_ALIAS => TYPE(USER_DERIVED_TYPE), &
             ALIAS_OF_TYPE_ALIAS => TYPE(TYPE_ALIAS)
			 
INTEGER(KIND = 8) :: I
TYPE(INTEGER_64) :: X, Y
TYPE(TYPE_ALIAS) :: S
TYPE(ALIAS_OF_TYPE_ALIAS) :: T

A type alias or the data type it aliases can be used interchangeably. That is, explicit or implicit declarations that use a type alias have the same effect as if the data type being aliased was used. For example, the above declarations of I, X, and Y are the same. Also, S and T are the same.

If the type being aliased is a derived type, the type alias name can be used to declare a structure constructor for the type.

The following are allowed as the type_spec in a TYPEALIAS statement:
  • Any intrinsic type defined by the Cray Fortran compiler.
  • Any type alias in the same scoping unit.
  • Any derived type in the same scoping unit.