[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP Fortran for OpenVMS
Language Reference Manual


Previous Contents Index

5.7.1 Making Arrays Equivalent

When you make an element of one array equivalent to an element of another array, the EQUIVALENCE statement also sets equivalences between the other elements of the two arrays. Thus, if the first elements of two equal-sized arrays are made equivalent, both arrays share the same storage. If the third element of a 7-element array is made equivalent to the first element of another array, the last five elements of the first array overlap the first five elements of the second array.

Two or more elements of the same array should not be associated with each other in one or more EQUIVALENCE statements. For example, you cannot use an EQUIVALENCE statement to associate the first element of one array with the first element of another array, and then attempt to associate the fourth element of the first array with the seventh element of the other array.

Consider the following valid example:


DIMENSION TABLE (2,2), TRIPLE (2,2,2)
EQUIVALENCE(TABLE(2,2), TRIPLE(1,2,2))

These statements cause the entire array TABLE to share part of the storage allocated to TRIPLE. Table 5-3 shows how these statements align the arrays.

Table 5-3 Equivalence of Array Storage
Array TRIPLE Array TABLE
Array
Element
Element
Number
Array
Element
Element
Number
TRIPLE(1,1,1) 1    
TRIPLE(2,1,1) 2    
TRIPLE(1,2,1) 3    
TRIPLE(2,2,1) 4 TABLE(1,1) 1
TRIPLE(1,1,2) 5 TABLE(2,1) 2
TRIPLE(2,1,2) 6 TABLE(1,2) 3
TRIPLE(1,2,2) 7 TABLE(2,2) 4
TRIPLE(2,2,2) 8    

Each of the following statements also aligns the two arrays as shown in Table 5-3:


EQUIVALENCE(TABLE, TRIPLE(2,2,1))
EQUIVALENCE(TRIPLE(1,1,2), TABLE(2,1))

You can also make arrays equivalent with nonunity lower bounds. For example, an array defined as A(2:3,4) is a sequence of eight values. A reference to A(2,2) refers to the third element in the sequence. To make array A(2:3,4) share storage with array B(2:4,4), you can use the following statement:


EQUIVALENCE(A(3,4), B(2,4))

The entire array A shares part of the storage allocated to array B. Table 5-4 shows how these statements align the arrays. The arrays can also be aligned by the following statements:


EQUIVALENCE(A, B(4,1))
EQUIVALENCE(B(3,2), A(2,2))

Table 5-4 Equivalence of Arrays with Nonunity Lower Bounds
Array B Array A
Array
Element
Element
Number
Array
Element
Element
Number
B(2,1) 1    
B(3,1) 2    
B(4,1) 3 A(2,1) 1
B(2,2) 4 A(3,1) 2
B(3,2) 5 A(2,2) 3
B(4,2) 6 A(3,2) 4
B(2,3) 7 A(2,3) 5
B(3,3) 8 A(3,3) 6
B(4,3) 9 A(2,4) 7
B(2,4) 10 A(3,4) 8
B(3,4) 11    
B(4,4) 12    

Only in the EQUIVALENCE statement can you identify an array element with a single subscript (the linear element number), even though the array was defined as multidimensional. For example, the following statements align the two arrays as shown in Table 5-4:


DIMENSION B(2:4,1:4), A(2:3,1:4)
EQUIVALENCE(B(6), A(4))

5.7.2 Making Substrings Equivalent

When you make one character substring equivalent to another character substring, the EQUIVALENCE statement also sets associations between the other corresponding characters in the character entities; for example:


CHARACTER NAME*16, ID*9
EQUIVALENCE(NAME(10:13), ID(2:5))

These statements cause character variables NAME and ID to share space (see Figure 5-1). The arrays can also be aligned by the following statement:


EQUIVALENCE(NAME(9:9), ID(1:1))

Figure 5-1 Equivalence of Substrings


If the character substring references are array elements, the EQUIVALENCE statement sets associations between the other corresponding characters in the complete arrays.

Character elements of arrays can overlap at any character position. For example, the following statements cause character arrays FIELDS and STAR to share storage (see Figure 5-2).


CHARACTER FIELDS(100)*4, STAR(5)*5
EQUIVALENCE(FIELDS(1)(2:4), STAR(2)(3:5))

Figure 5-2 Equivalence of Character Arrays


The EQUIVALENCE statement cannot assign the same storage location to two or more substrings that start at different character positions in the same character variable or character array. The EQUIVALENCE statement also cannot assign memory locations in a way that is inconsistent with the normal linear storage of character variables and arrays.

5.7.3 EQUIVALENCE and COMMON Interaction

A common block can extend beyond its original boundaries if variables or arrays are associated with entities stored in the common block. However, a common block can only extend beyond its last element; the extended portion cannot precede the first element in the block.

Examples

Figure 5-3 and Figure 5-4 demonstrate valid and invalid extensions of the common block, respectively.

Figure 5-3 A Valid Extension of a Common Block


Figure 5-4 An Invalid Extension of a Common Block


The second example is invalid because the extended portion, B(1), precedes the first element of the common block.

The following example shows a valid EQUIVALENCE statement and an invalid EQUIVALENCE statement in the context of a common block.


COMMON A, B, C
DIMENSION D(3)
EQUIVALENCE(B, D(1))      ! Valid, because common block is extended
                          ! from the end.

COMMON A, B, C
DIMENSION D(3)
EQUIVALENCE(B, D(3))      ! Invalid, because D(1) would extend common
                          ! block to precede A's location.

5.8 EXTERNAL Attribute and Statement

The EXTERNAL attribute allows an external or dummy procedure to be used as an actual argument. (To specify intrinsic procedures as actual arguments, use the INTRINSIC attribute.)

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

Type Declaration Statement:


  • type, [att-ls,] EXTERNAL [,att-ls] :: ex-pro [,ex-pro]...

Statement:


  • EXTERNAL ex-pro [,ex-pro]...

type

Is a data type specifier.

att-ls

Is an optional list of attribute specifiers.

ex-pro

Is the name of an external (user-supplied) procedure or dummy procedure.

Rules and Behavior

In a type declaration statement, only functions can be declared EXTERNAL. However, you can use the EXTERNAL statement to declare subroutines and block data program units, as well as functions, to be external.

The name declared EXTERNAL is assumed to be the name of an external procedure, even if the name is the same as that of an intrinsic procedure. For example, if SIN is declared with the EXTERNAL attribute, all subsequent references to SIN are to a user-supplied function named SIN, not to the intrinsic function of the same name.

You can include the name of a block data program unit in the EXTERNAL statement to force a search of the object module libraries for the block data program unit at link time. However, the name of the block data program unit must not be used in a type declaration statement.

Examples

The following example shows type declaration statements specifying the EXTERNAL attribute:


PROGRAM TEST
...
INTEGER, EXTERNAL :: BETA
LOGICAL, EXTERNAL :: COS
...
CALL SUB(BETA)       ! External function BETA is an actual argument

You can use a name specified in an EXTERNAL statement as an actual argument to a subprogram, and the subprogram can then use the corresponding dummy argument in a function reference or a CALL statement; for example:


EXTERNAL FACET
CALL BAR(FACET)

SUBROUTINE BAR(F)
EXTERNAL F
CALL F(2)

Used as an argument, a complete function reference represents a value, not a subprogram; for example, FUNC(B) represents a value in the following statement:


CALL SUBR(A, FUNC(B), C)

For More Information:

  • On type declaration statements, see Section 5.1.
  • On intrinsic procedures, see Chapter 9.
  • On the INTRINSIC attribute, see Section 5.11.
  • On compatible attributes, see Table 5-1.
  • On a compiler option that changes the interpretation of the EXTERNAL statement, see Section B.4.

5.9 IMPLICIT Statement

The IMPLICIT statement overrides the default implicit typing rules for names. (The default data type is INTEGER for names beginning with the letters I through N, and REAL for names beginning with any other letter.)

The IMPLICIT statement takes one of the following forms:


  • IMPLICIT type (a[,a]...)[, type (a[,a]...)]...
  • IMPLICIT NONE

type

Is a data type specifier (CHARACTER*(*) is not allowed).

a

Is a single letter, a dollar sign ($), or a range of letters in alphabetical order. The form for a range of letters is a _1 -a _2 , where the second letter follows the first alphabetically (for example, A-C).

The dollar sign can be used at the end of a range of letters, since IMPLICIT interprets the dollar sign to alphabetically follow the letter Z. For example, a range of X-$ would apply to identifiers beginning with the letters X, Y, Z, or $.

Rules and Behavior

The IMPLICIT statement assigns the specified data type (and kind parameter) to all names that have no explicit data type and begin with the specified letter or range of letters. It has no effect on the default types of intrinsic procedures.

When the data type is CHARACTER*len, len is the length for character type. The len is an unsigned integer constant or an integer initialization expression enclosed in parentheses. The range for len is 1 to 65535.

Names beginning with a dollar sign ($) are implicitly INTEGER.

The IMPLICIT NONE statement disables all implicit typing defaults. When IMPLICIT NONE is used, all names in a program unit must be explicitly declared. An IMPLICIT NONE statement must precede any PARAMETER statements, and there must be no other IMPLICIT statements in the scoping unit.

Note

To receive diagnostic messages when variables are used but not declared, you can specify a compiler option instead of using IMPLICIT NONE.

The following IMPLICIT statement represents the default typing for names when they are not explicitly typed:


IMPLICIT INTEGER (I-N), REAL (A-H, O-Z)

Examples

The following are examples of the IMPLICIT statement:


IMPLICIT DOUBLE PRECISION (D)
IMPLICIT COMPLEX (S,Y), LOGICAL(1) (L,A-C)
IMPLICIT CHARACTER*32 (T-V)
IMPLICIT CHARACTER*2 (W)
IMPLICIT TYPE(COLORS) (E-F), INTEGER (G-H)

For More Information:

On compiler options, see the HP Fortran for OpenVMS User Manual.

5.10 INTENT Attribute and Statement

The INTENT attribute specifies the intended use of one or more dummy arguments.

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

Type Declaration Statement:


  • type, [att-ls,] INTENT (intent-spec) [,att-ls] :: d-arg [, d-arg]...

Statement:


  • INTENT (intent-spec) [::] d-arg [, d-arg]...

type

Is a data type specifier.

att-ls

Is an optional list of attribute specifiers.

intent-spec

Is one of the following specifiers:
  • IN
    Specifies that the dummy argument will be used only to provide data to the procedure. The dummy argument must not be redefined (or become undefined) during execution of the procedure.
    Any associated actual argument must be an expression.

  • OUT
    Specifies that the dummy argument will be used to pass data from the procedure back to the calling program. The dummy argument is undefined on entry and must be defined before it is referenced in the procedure.
    Any associated actual argument must be definable.
  • INOUT
    Specifies that the dummy argument can both provide data to the procedure and return data to the calling program.
    Any associated actual argument must be definable.

d-arg

Is the name of a dummy argument. It cannot be a dummy procedure or dummy pointer.

Rules and Behavior

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

If no INTENT attribute is specified for a dummy argument, its use is subject to the limitations of the associated actual argument.

If a function specifies a defined operator, the dummy arguments must have intent IN.

If a subroutine specifies defined assignment, the first argument must have intent OUT or INOUT, and the second argument must have intent IN.

A dummy argument with intent IN (or a subobject of such a dummy argument) must not appear as any of the following:

  • A DO variable or implied-DO variable
  • The variable of an assignment statement
  • The pointer-object of a pointer assignment statement
  • An object or STAT= variable in an ALLOCATE or DEALLOCATE statement
  • An input item in a READ statement
  • A variable name in a NAMELIST statement if the namelist group name appears in a NML= specifier in a READ statement
  • An internal file unit in a WRITE statement
  • A definable variable in an INQUIRE statement
  • An IOSTAT= or SIZE= specifier in an I/O statement
  • An actual argument in a reference to a procedure with an explicit interface if the associated dummy argument has intent OUT or INOUT

If an actual argument is an array section with a vector subscript, it cannot be associated with a dummy array that is defined or redefined (has intent OUT or INOUT).

Examples

The following example shows type declaration statements specifying the INTENT attribute:


SUBROUTINE TEST(I, J)
  INTEGER, INTENT(IN) :: I
  INTEGER, INTENT(OUT), DIMENSION(I) :: J

The following are examples of the INTENT statement:


SUBROUTINE TEST(A, B, X)
   INTENT(INOUT) :: A, B
   ...

SUBROUTINE CHANGE(FROM, TO)
   USE EMPLOYEE_MODULE
   TYPE(EMPLOYEE) FROM, TO
   INTENT(IN) FROM
   INTENT(OUT) TO
   ...

For More Information:

5.11 INTRINSIC Attribute and Statement

The INTRINSIC attribute allows the specific name of an intrinsic procedure to be used as an actual argument. (Not all specific names can be used as actual arguments. For more information, see Table 9-1.)

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

Type Declaration Statement:


  • type, [att-ls,] INTRINSIC [,att-ls] :: in-pro [,in-pro]...

Statement:


  • INTRINSIC in-pro [,in-pro]...

type

Is a data type specifier.

att-ls

Is an optional list of attribute specifiers.

in-pro

Is the name of an intrinsic procedure.

Rules and Behavior

In a type declaration statement, only functions can be declared INTRINSIC. However, you can use the INTRINSIC statement to declare subroutines, as well as functions, to be intrinsic.

The name declared INTRINSIC is assumed to be the name of an intrinsic procedure. If a generic intrinsic function name is given the INTRINSIC attribute, the name retains its generic properties.

Examples

The following example shows a type declaration statement specifying the INTRINSIC attribute:


PROGRAM EXAMPLE
...
REAL(8), INTRINSIC :: DACOS
...
CALL TEST(X, DACOS)     ! Intrinsic function DACOS is an actual argument

The following example shows an INTRINSIC statement:

Main Program Subprogram
EXTERNAL CTN SUBROUTINE TRIG(X,F,Y)
INTRINSIC SIN, COS Y = F(X)
. . . RETURN
  END
CALL TRIG(ANGLE,SIN,SINE)  
. . . FUNCTION CTN(X)
  CTN = COS(X)/SIN(X)
CALL TRIG(ANGLE,COS,COSINE) RETURN
. . . END
CALL TRIG(ANGLE,CTN,COTANGENT)  

Note that when TRIG is called with a second argument of SIN or COS, the function reference F(X) references the Fortran 95/90 library functions SIN and COS; but when TRIG is called with a second argument of CTN, F(X) references the user function CTN.

For More Information:


Previous Next Contents Index