Previous | Contents | Index |
When operators are defined for functions, the functions can then be referenced as defined operations.
The operators are defined by using a generic interface block specifying OPERATOR, followed by the defined operator (in parentheses).
A defined operation is not an intrinsic operation. However, you can use a defined operation to extend the meaning of an intrinsic operator.
For defined unary operations, the function must contain one argument. For defined binary operations, the function must contain two arguments.
Interpretation of the operation is provided by the function that defines the operation.
A Fortran 95/90 defined operator can contain up to 31 letters, and is enclosed in periods (.). Its name cannot be the same name as any of the following:
An intrinsic operator can be followed by a defined unary operator.
The result of a defined operation can have any type. The type of the result (and its value) must be specified by the defining function.
The following examples show expressions containing defined operators:
.COMPLEMENT. A X .PLUS. Y .PLUS. Z M * .MINUS. N |
Table 4-1 shows the precedence of all intrinsic and defined operators:
Category | Operator | Precedence |
---|---|---|
Defined Unary Operators | Highest | |
Numeric | ** | . |
Numeric | * or / | . |
Numeric | Unary + or -- | . |
Numeric | Binary + or -- | . |
Character | // | . |
Relational |
.EQ., .NE., .LT., .LE., .GT., .GE.
==, /=, <, <=, >, >= |
. |
Logical | .NOT. | . |
Logical | .AND. | . |
Logical | .OR. | . |
Logical | .XOR., .EQV., .NEQV. | . |
Defined Binary Operators | Lowest |
A constant expression contains intrinsic operations and parts that are all constants. An initialization expression is a constant expression that is evaluated when a program is compiled. A specification expression is a scalar, integer expression that is restricted to declarations of array bounds and character lengths.
Initialization and specification expressions can appear in
specification statements, with some restrictions.
4.1.7.1 Initialization Expressions
An initialization expression must evaluate at compile time to a constant. It is used to specify an initial value for an entity.
In an initialization expression, each operation is intrinsic and each operand is one of the following:
BIT_SIZE | MINEXPONENT |
DIGITS | PRECISION |
EPSILON | RADIX |
HUGE | RANGE |
ILEN | SHAPE |
KIND | SIZE |
LBOUND | TINY |
LEN | UBOUND |
MAXEXPONENT |
REPEAT | SELECTED_REAL_KIND |
RESHAPE | TRANSFER |
SELECTED_INT_KIND | TRIM |
Each subscript, section subscript, and substring starting and ending point must be an initialization expression.
If an initialization expression invokes an inquiry function for a type parameter or an array bound of an object, the type parameter or array bound must be specified in a prior specification statement (or to the left of the inquiry function in the same statement).
In a specification expression, the number of arguments for a function reference is limited to 255.
The following examples show valid and invalid initialization (constant) expressions:
Valid | |
-1 + 3 | |
SIZE(B) | ! B is a named constant |
7_2 | |
INT(J, 4) | ! J is a named constant |
SELECTED_INT_KIND (2) | |
Invalid | Explanation |
SUM(A) | Not an allowed function. |
A/4.1 - K**1.2 | Exponential does not have integer power (A and K are named constants). |
HUGE(4.0) | Argument is not an integer. |
A specification expression is a restricted expression that is of type integer and has a scalar value. This type of expression appears only in the declaration of array bounds and character lengths.
In a restricted expression, each operation is intrinsic and each operand is one of the following:
BIT_SIZE | NWORKERS |
DIGITS | PRECISION |
EPSILON | PROCESSORS_SHAPE |
HUGE | RADIX |
ILEN | RANGE |
KIND | SHAPE |
LBOUND | SIZE |
LEN | SIZEOF |
MAXEXPONENT | TINY |
MINEXPONENT | UBOUND |
NUMBER_OF_PROCESSORS |
Each subscript, section subscript, and substring starting and ending point must be a restricted expression.
Specification functions can be used in specification expressions to indicate the attributes of data objects. A specification function is a pure function. It cannot have a dummy procedure argument or be any of the following:
A variable in a specification expression must have its type and type parameters (if any) specified in one of the following ways:
If a variable in a specification expression is typed by the implicit typing rules, its appearance in any subsequent type declaration statement must confirm the implied type and type parameters.
If a specification expression invokes an inquiry function for a type parameter or an array bound of an object, the type parameter or array bound must be specified in a prior specification statement (or to the left of the inquiry function in the same statement).
The following shows valid specification expressions:
MAX(I) + J ! I and J are scalar integer variables UBOUND(ARRAY_B,20) ! ARRAY_B is an assumed-shape dummy array |
An assignment statement causes variables to be defined or redefined. This section describes the following kinds of assignment statements: intrinsic, defined, pointer, masked array (WHERE), and element array (FORALL).
The ASSIGN statement assigns a label to an integer variable. It is
discussed in Section 7.2.3.
4.2.1 Intrinsic Assignments
Intrinsic assignment is used to assign a value to a nonpointer variable. In the case of pointers, intrinsic assignment is used to assign a value to the target associated with the pointer variable. The value assigned to the variable (or target) is determined by evaluation of the expression to the right of the equal sign.
An intrinsic assignment statement takes the following form:
|
variable
Is the name of a scalar or array of intrinsic or derived type (with no defined assignment). The array cannot be an assumed-size array, and neither the scalar nor the array can be declared with the PARAMETER or INTENT(IN) attribute.expression
Is of intrinsic type or the same derived type as variable. Its shape must conform with variable. If necessary, it is converted to the same type and kind as variable.
Before a value is assigned to the variable, the expression part of the assignment statement and any expressions within the variable are evaluated. No definition of expressions in the variable can affect or be affected by the evaluation of the expression part of the assignment statement.
When the run-time system assigns a value to a scalar integer or character variable and the variable is shorter than the value being assigned, the assigned value may be truncated and significant bits (or characters) lost. This truncation can occur without warning, and can cause the run-time system to pass incorrect information back to the program. |
If the variable is a pointer, it must be associated with a definable target. The shape of the target and expression must conform and their type and kind parameters must match.
The following sections discuss numeric, logical, character, derived-type, and array intrinsic assignment.
For numeric assignment statements, the variable and expression must be numeric type.
The expression must yield a value that conforms to the range requirements of the variable. For example, a real expression that produces a value greater than 32767 is invalid if the entity on the left of the equal sign is an INTEGER(2) variable.
Significance can be lost if an INTEGER(4) value, which can exactly represent values of approximately the range --2*10**9 to +2*10**9, is converted to REAL(4) (including the real part of a complex constant), which is accurate to only about seven digits.
If the variable has the same data type as that of the expression on the right, the statement assigns the value directly. If the data types are different, the value of the expression is converted to the data type of the variable before it is assigned.
Table 4-2 summarizes the data conversion rules for numeric assignment statements.
Scalar Memory | Expression (E) | |
---|---|---|
Reference (V) | Integer, Logical or Real | Complex |
Integer or Logical | V=INT(E) |
V=INT(REAL(E))
Imaginary part of E is not used. |
REAL
(KIND=4) |
V=REAL(E) |
V=REAL(REAL(E))
Imaginary part of E is not used. |
REAL
(KIND=8) |
V=DBLE(E) |
V=DBLE(REAL(E))
Imaginary part of E is not used. |
REAL
(KIND=16) |
V=QEXT(E) |
V=QEXT(REAL(E))
Imaginary part of E is not used. |
COMPLEX
(KIND=4) |
V=CMPLX(REAL(E), 0.0) | V=CMPLX(REAL(REAL(E)), REAL(AIMAG(E))) |
COMPLEX
(KIND=8) |
V=CMPLX(DBLE(E), 0.0) | V=CMPLX(DBLE(REAL(E)), DBLE(AIMAG(E))) |
COMPLEX
(KIND=16) |
V=CMPLX(QEXT(E), 0.0) | V=CMPLX(QEXT(REAL(E)), QEXT(AIMAG(E))) |
For more information on the referenced intrinsic functions, see Chapter 9.
The following examples demonstrate valid and invalid numeric assignment statements:
Valid | |
BETA = -1./(2.*X)+A*A/(4.*(X*X)) | |
PI = 3.14159 | |
SUM = SUM + 1. | |
ARRAY_A = ARRAY_B + ARRAY_C + SCALAR_I |
! Valid if all arrays conform in
! shape |
Invalid | Explanation |
3.14 = A - B | Entity on the left must be a variable. |
ICOUNT = A//B(3:7) | Implicitly typed data types do not match. |
SCALAR_I = ARRAY_A(:) | Shapes do not match. |
Previous | Next | Contents | Index |