Previous | Contents | Index |
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.
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)) |
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)) |
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.
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. |
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:
|
Statement:
|
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.
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.
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) |
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:
|
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 $.
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.
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) |
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) |
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:
|
Statement:
|
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.
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:
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).
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 ... |
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:
|
Statement:
|
type
Is a data type specifier.att-ls
Is an optional list of attribute specifiers.in-pro
Is the name of an intrinsic procedure.
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.
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.
Previous | Next | Contents | Index |