In Fortran, calculations are specified by writing expressions. Expressions look much like algebraic formulas in mathematics, particularly when the expressions involve calculations on numerical values.
Expressions often involve nonnumeric values, such as character strings, logical values, or structures; these also can be considered to be formulas that involve nonnumeric quantities rather than numeric ones.
This chapter describes how valid expressions can be formed, how they are interpreted, and how they are evaluated. One of the major uses of expressions is in assignment statements where the value of an expression is assigned to a variable. The assignment statement appears in four forms: intrinsic assignment, defined assignment, masked array assignment, and pointer assignment. In the first three forms, a value is computed by performing the computation specified in an expression and the value is assigned to a variable. In the fourth form, a pointer, the object on the left side, is made to point to the object or target on the right side. The four forms of the assignment statement are also described in this chapter.
Note: : The Fortran statement syntax in this manual is defined using the same terms used in the Fortran standard. In this chapter, however, certain terms from the standard have been changed to improve clarity. 
Fortran allows you to define data types, operators for these types, and operators for intrinsic types. These capabilities are provided within the general framework for expressions, which consists of three sets of rules:
The rules for forming a valid expression
The rules for interpreting the expression (giving it a meaning)
The rules for evaluating the expression (how the computation may be carried out)
An expression is formed from operators and operands. There is no change from FORTRAN 77 in the rules for forming expressions, except that a new class of operators has been defined. These are userdefined operators, which are either unary or binary operators. They have the form of a sequence of letters surrounded by periods; .INVERSE. and .PLUS. are examples of possible userdefined operators.
The formal (BNF) rules for forming expressions imply an order for combining operands with operators. These rules specify that expressions enclosed in parentheses are combined first and that, for example, the multiply operator * is combined with its operands before the addition operator + is combined with its operands. This order for operators in the absence of specific parentheses is called the operator precedence and is summarized in Section 7.2.5. New operators, such as == and >=, have the same precedence and meaning as .EQ. and .GE., respectively.
The formation rules for expressions imply that the defined unary operators have highest precedence of all operators, and defined binary operators have the lowest precedence of all operators. When they appear in a context where two or more of these operators of the same precedence are adjacent, the operands are combined with their operators in a lefttoright manner, as is the case for the familiar + and  operators, or in a righttoleft manner for the exponentiation operator (**).
Intrinsic operators are generic in the sense that they can operate on operands of different types. For example, the plus operator + operates on operands of type integer as well as real and complex. Intrinsic operators can be extended further by the programmer to operate on operands of types for which there are no intrinsic operations. Similarly, you can use defined unary and defined binary operators to operate on operands of types for which there are no previous definitions. The MIPSpro Fortran Language Reference Manual, Volume 2, describes how any operator can be made generic by the programmer using a generic specifier on an interface block.
The rules for interpretation of an expression are provided by the interpretation of each operator in the expression. When the operator is an intrinsic operator such as +, *, or .NOT., and the operands are of intrinsic types allowed for the intrinsic operator, the interpretation is provided by the usual mathematical or symbolic meaning of the operation. Thus, + with two numeric operands means that the two operands are added together. For the userdefined operators, the interpretation is provided by a usersupplied function subprogram with a designation that this subprogram is to be used to define the operation. Fortran allows the intrinsic operator symbols to be extended to cases in which the operands are not of the usual intrinsic types defined by the standard. For example, the + operator can be defined for operands of type RATIONAL (a userdefined type) or for operands of type logical with the interpretation provided by a usersupplied function subprogram. The rules for construction of expressions (the syntax rules) are the same for userdefined operators as for intrinsic operators.
The general rule for evaluation of a Fortran expression states that any method that is mathematically equivalent to that provided by the construction and interpretation rules for the expression is permitted, provided the order of evaluation indicated by explicit parentheses in the expression is followed. Thus, a compiler has a great deal of freedom to rearrange or optimize the computation, provided the rearranged expression has the same mathematical meaning.
Arrays and pointers as objects can appear in expressions and assignment statements. This chapter describes using arrays and pointers in the following contexts:
As operands of intrinsic and userdefined operations
As the variables being assigned in intrinsic assignment statements
As the variables in pointer assignment statements and masked array assignment statements
The result obtained from the evaluation of an expression can be used in many ways. For example, it can be printed or passed to a subprogram. In many cases, however, the value is assigned to a variable and that value can be used later in the program by referencing the variable.
Execution of the assignment statement causes the expression to be evaluated (by performing the computation indicated), and then the value of the expression is assigned to the variable on the left of the equal sign.
The following example shows an assignment statement:
REAL_AGE = REPORTED_AGE + 3.0 
REPORTED_AGE + 3.0 is the expression that indicates how to compute a value, which is assigned to the variable REAL_AGE.
The following example involves subscripts:
A(I+3) = PI + A(I3) 
The value of the subscript expression I3 is determined and the value of the I3 element of A is added to the value of PI to produce a sum. Before the result of this expression is assigned, the value of the subscript expression I+3 is determined and the value of the sum is assigned to the element I+3 of A.
The previous examples are arithmetic. Fortran has expressions of other types, such as logical, character, and derived type. Values of expressions of these other types can be assigned to variables of these other types. As with operators, the programmer can extend the meaning of assignment to types not defined intrinsically and can redefine assignment for two objects of the same derived type. Such assignments are called defined assignments. In addition, arrays and pointers each have special forms of assignment statements called masked array assignment and pointer assignment, respectively. These two assignment statement forms are described later in this chapter.
An assignment statement is only one of the Fortran statements in which expressions may occur. Expressions also can appear in subscripts, actual arguments, IF statements, PRINT statements, WHERE statements, declaration statements, and many other statements.
An expression represents a computation that results in a value and can be as simple as a constant or variable. The value of an expression has a type and can have zero, one, or two type parameter values. If the value is of a derived type, it has no type parameter. If it is of an intrinsic type, it has a kind type parameter, and if, in addition, it is of the type character, it has a character length parameter. In addition, the value is a scalar (including a structure) or an array.
A complex value or a structure value is a scalar, even though it can consist of more than one value (for example, a complex value consists of two real values).
Arrays and pointers can be used as operands of intrinsic and defined operators. For intrinsic operators, when an array is an operand, the operation is performed elementwise on the elements of the array. For intrinsic operators, when a pointer is an operand, the value of the target pointed to by (associated with) the pointer is used as the operand. For defined operators, the array or pointer is used in a manner determined by the procedure defining the operation.
As indicated in the introduction to this chapter, the presentation of expressions is described in terms of the following three basic sets of rules:
The rules for forming expressions (syntax)
The rules for interpreting expressions (semantics)
The rules for evaluating expressions (optimization)
The syntax rules indicate which forms of expressions are valid. The semantics indicate how each expression is to be interpreted. After an expression has been given an interpretation, a compiler can evaluate another completely different expression, provided the expression evaluated is mathematically equivalent to the one written.
To see how this works, consider the expression 2 * A + 2 * B in the following PRINT statement:
PRINT *, 2 * A + 2 * B 
The syntax rules described later in this chapter indicate that the expression is valid and suggest an order of evaluation. The semantic rules specify the operations to be performed, which in this case, are the multiplication of the values of A and B by 2 and the addition of the two results. That is, the semantic rules indicate that the expression is to be interpreted as if it were the following:
((2 * A) + (2 * B)) 
After the correct interpretation has been determined, the Fortran rules of evaluation allow a different expression to be used to evaluate the expression, provided the different expression is mathematically equivalent to the one written. For example, a processor can first add A and B and then multiply the result by 2, because the following expression is mathematically equivalent to the one written:
2 * (A + B) 
Although alternative evaluations are allowed, three properties should be noted:
Parentheses must not be violated. Consider the following expression:
(2 * A) + (2 * B) 
This expression must not be evaluated as follows:
2 * (A + B) 
This gives the programmer some control over the method of evaluation.
Integer division is not mathematically equivalent to real division. The value of 3/2 is 1 and so cannot be evaluated as 3*0.5, which is 1.5.
Mathematically equivalent expressions can produce computationally different results because of the implementation of arithmetic and rounding on computer systems. For example, the expression X/2.0 could be evaluated as 0.5*X, even though the results may be slightly different. Also, for example, the expression 2 * A + 2 * B could be evaluated as 2*(A+B); when A and B are of type real, the two mathematically equivalent expressions may yield different values because of different rounding errors and different arithmetic exceptions in the two expressions.
An expression is formed from operands, operators, and parentheses. The simplest form of an expression is a constant or a variable.
Expression  Meaning  
3.1416  A real constant  
.TRUE.  A logical constant  
X  A scalar variable  
Y  An array variable  
Y(K)  A variable that is an array element of Y  
Y(2:10:2)  A variable that is an array subsection of Y  
M%N  A variable that is a component of a structure M  
Y(K)(I:I+3)  A variable that is a substring of array element Y(K) 
The values of these simple expressions are the constant value 3.1416, the constant value .TRUE., the value of the variable X, the value of the array Y, the value of the array element Y(K), the value of the array subsection Y(2:10:2), the value of the component N of structure M, and the value of a substring of an array element Y(K), respectively.
An operand in an expression can be one of the following items:
A constant or subobject of a constant
A variable (for example, a scalar, an array, a substring, or a pointer)
An array constructor
A structure constructor
A function reference (returning, for example, a scalar, an array, a character variable, or a pointer)
Another expression in parentheses
The following examples show operands:
A ! scalar or an array B(1) ! array element or function C(3:5) ! array section or a substring (A + COS(X)) ! expression in parentheses (/ 1.2, 2.41 /)! array constructor RATIONAL(1,2) ! structure constructor or function I_PTR ! pointer to an integer target 
There are two forms that operations can take in an expression. One is an operation involving two operands, such as multiplying two numbers together. The other is an operation on one operand, such as making a number negative. These forms are called binary and unary operations, respectively.
Table 71 lists the intrinsic operators. You can use function subprograms to define additional operators. Userdefined operators are either binary or unary operators.
Table 71. Intrinsic operators and the allowed types of their operands
Operator category  Intrinsic operator  Operand types 

Arithmetic  **, *, /, +, , unary +, unary   Numeric of any combination of numeric types and kind type parameters or Cray pointer. Cray pointers are only allowed with the + or  operators. 
Character  //  Character of any length. 
Relational  .EQ., .NE., ==, /=  Both of any numeric type and any kind type parameter or Cray pointer, or both of type character with any character length parameter. 
Relational  .GT., .GE., .LT., .LE., >, >=, <, <=  Both of any numeric type (except complex) and any kind type parameter or Cray pointer, or both of type character with any character length parameter. 
Logical  .NOT., .AND., .OR., .XOR., .EQV., .NEQV.  Both of type logical with any combination of kind type parameters. 
Bitwise masking (Boolean) expressions (EXT)  .NOT., .AND., .OR., .XOR., .EQV., .NEQV.  Integer, real, typeless, or Cray pointer. 
Note: The Fortran standard does not specify the bitwise masking (Boolean) expressions, nor does it specify the .XOR. operator as a logical operator. 
A binary operator combines two operands, as in the following:
x_{1} operator x_{2} 
Examples:
A + B 2 * C 
The examples show an addition between two operands A and B, and a multiplication of two operands, the constant 2 and the operand C.
A unary operation acts on one operand, as in the following:
operator x_{1} 
Examples:
 C .NOT. L 
The first example results in the value minus C. The second example produces a value that is the logical complement of L; the operator .NOT. is the only intrinsic operator that is a unary operator and is never a binary operator.
Intrinsic operations are those whose definitions are known to the compiler. They are built into Fortran and are always available for use in expressions. Table 71, lists the operators built into Fortran as specified by the standard.
The relational operator symbols ==, /=, >, >=, <, and <= are synonyms for the operators .EQ., .NE., .GT., .GE., .LT., and .LE., respectively.
The less than or greater than operation is represented by the <> operator and the .LG. keyword. This operation is suggested by the IEEE standard for floatingpoint arithmetic, and the compiler supports this operator. Only values of type real can appear on either side of the <> or .LG. operators. If the operands are not of the same kind type value, the compiler converts them to equivalent kind types. This operator's functionality differs slightly, depending on your platform. The <> and .LG. operators perform a lessthanorgreaterthan operation as specified in the IEEE standard for floatingpoint arithmetic.
Note: The Fortran standard does not specify the <> or .LG. operators. 
The compiler allows abbreviations for the logical and masking operators. The abbreviations .A., .O., .N., and .X. are synonyms for .AND., .OR., .NOT., and .XOR., respectively. If you define the abbreviated operator for any type, the abbreviated form of the intrinsic operator cannot be used in any scope in which the defined operator is accessible.
Note: The Fortran standard does not specify abbreviations for the logical and masking operators. 
In addition to the Fortran operators that are intrinsic (built in), there may be userdefined operators in expressions.
Defined operations are those that you define in the Fortran program and are made available to each program unit that uses them. The computation performed by a defined operation is described explicitly in a function that must appear as a subprogram in the Fortran program where it is used. The operator used in a defined operation is called a defined operator. In this way, you extend the repertoire of operations so that computations can be expressed in a natural way using operator notation. Function subprograms that define operators are explained in detail in the MIPSpro Fortran Language Reference Manual, Volume 2.
A defined operator uses a symbol that is either the symbol for an intrinsic operator or is a new operator symbol. The synonyms described above for the relational operators remain synonyms in all contexts, even when there are defined operators. For example, if the operator < is defined for a new type, say STRING, the same definition applies to the operator .LT. for the type STRING; if the operator .LT. is specified as private, the operator < is also private.
A distinction is made between a defined (or new) operator and an extended intrinsic operator. An extended intrinsic operator is one that uses the same symbol as an intrinsically defined Fortran operator, like plus + or multiply *. It also causes the operations to be combined in the same order as is specified for the intrinsic operator. A defined operator is one where the operator symbol is not the same as an intrinsic operator but is new, such as the .INVERSE. operator. Defined operators, however, have a fixed precedence; defined unary operators have the highest precedence of all operators, and defined binary operators have the lowest precedence of all operators. The precedences of all operators are described in more detail in Section 7.2.5.
A defined elemental operation is a defined operation for which the function is elemental.
Note: The masking or Boolean operators and their abbreviations, which are extensions to Fortran, can be redefined as defined operators. If you redefine a masking operator, your definition overrides the intrinsic masking operator definition. See Table 71, for a list of the operators. 
Expressions are formed by combining operands. Operands can be constants, variables (scalars, array elements, arrays, array sections, structures, structure components, and pointers), array constructors, structure constructors, functions, and parenthesized expressions with intrinsic and defined operators.
The method used to specify the expression formation rules is a collection of syntax rules that determine the forms of expressions. The order of evaluation of the operations in an expression is determined by the usual semantics for the operations, and the syntax rules are designed to be consistent with these semantics. In fact, the order of evaluation defines a precedence order for operators that is summarized in Table 72.
Table 72. The hierarchy of expressions through forms
Term  Definition 

expression  [ expression defined_operator ] equivalence_expression 
equivalence_expression  [ equivalence_expression .EQV. ] disjunct_expression equivalence_expression .NEQV. disjunct_expression 
Exclusive OR (extension)  [ disjunct_expression .XOR. ] conjunct_expression 
disjunct_expression  [ disjunct_expression .OR. ] conjunct_expression 
conjunct_expression  [ conjunct_expression .AND. ] not_expression 
not_expression  [ .NOT. ] comparison_expression 
comparison_expression  [ concatenation_expression relational_operator ] concatenation_expression 
concatenation_expression  [ concatenation_expression // ] summation_expression 
summation_expression  [ summation_expression + ] multiplication_expression summation_expression  multiplication_expression + multiplication_expression  multiplication_expression 
multiplication_expression  [ multiplication_expression * ] exponentiation_expression multiplication_expression / exponentiation_expression 
exponentiation_expression  defined_unary_expression [ ** exponentiation_expression ] 
defined_unary_expression  [ defined_operator ] primary 
primary  constant constant_subobject variable array_constructor structure_constructor function_reference (expression) 
The set of syntax rules defines an expression at the highest level in terms of operators and operands, which are themselves expressions. As a result, the formal set of rules is recursive. The basic or lowest level of an expression is a primary, which, for example, can be a variable, a constant, or a function, or recursively an expression enclosed in parentheses. The rules for forming expressions are described from the lowest or most primitive level to the highest or most complex level; that is, the rules are stated from a primary up to an expression.
A primary is defined as follows:
 primary  is 
 

 or 
 

 or 
 

 or 
 

 or 
 

 or 
 

 or 
 
 constant_subobject  is 

A variable that is a primary must not be a whole assumedsize array or a section of an assumedsize array name, unless the last subscript position of the array is specified with a scalar subscript or a section subscript in which the upper bound is specified.
The following examples show primaries:
Primary  Meaning  
3.2  A real constant  
ONE  A named constant  
'ABCS'(I:I)  A constant subobject  
A  A variable (scalar, array, structure, or pointer)  
B(:,1:N)  An assumedsize array with an upper bound in the last dimension  
C(I)  An array element  
CH(I:J)  A substring  
(/ 1, J, 7 /)  An array constructor  
RATIONAL(I, J)  A structure constructor  
FCN(A)  A function reference  
(A * B)  A parenthesized expression 
In the previous examples, ONE is a named constant if it has the PARAMETER attribute or appears in a PARAMETER statement. 'ABCS'(I:I) is a constant subobject even though I may be a variable because its parent ('ABCS') is a constant; the reference 'ABCS'(I:I) is a constant subobject because it cannot be defined like a variable can be defined. RATIONAL is a derived type and FCN is a userdefined function.
When an array variable is a primary, the whole array is used, except in a masked assignment statement. In a masked assignment statement, only that part of the array specified by the mask is used.
When a pointer is a primary, the target associated with (pointed to by) the pointer is used, except possibly when the pointer is an actual argument of a procedure, or is an operand of a defined operation or a defined assignment. Whether the pointer or the target is used in these exceptional cases is determined by the procedure invoked by the reference.
Recall that an assumedsize array is a dummy argument whose shape is not completely specified in the subprogram in that the extent in the last dimension is determined by its corresponding actual argument. The implementation model is that the extent in the last dimension is never known to the subprogram but is specified by the use of a subscript, section subscript, or vector subscript expression that defines an upper bound in the last dimension. Unless the extent is specified in this way, such an object must not be used as a primary in an expression. On the other hand, if a subscript, section subscript with an extent for the upper bound, or a vector subscript is specified for the last dimension, the array value has a welldefined shape and hence can be used as a primary in any expression. For example, if A is declared as REAL A(3,*), array A(:,3) has a welldefined shape and can be used as a primary in an expression.
Expressions can be used as actual arguments in procedure references (function references or subroutine calls). Because actual arguments can be expressions involving operations, actual arguments must not contain assumedsize arrays, unless their shape is welldefined, as described above. An actual argument, however, can be just a variable, which then allows the actual argument to be the name of an assumedsize array. This implies that such actual arguments can be assumedsize arrays, unless the procedure requires the shape of the argument to be specified by the actual argument. Most of the intrinsic procedures that allow array arguments require the shape to be specified for the actual array arguments, and therefore assumedsize arrays cannot be used as actual arguments for most intrinsic functions. The exceptions are all references to the intrinsic function LBOUND(3i), and certain references to the intrinsic functions UBOUND(3i) and SIZE(3i).
Defined unary expressions have the highest operator precedence. A defined unary expression is a defined operator followed by a primary. These are defined as follows:
 defined_unary_expr  is 
 
 defined_operator  is 

A defined operator must not contain more than 31 letters.
A defined operator must not be the same as any intrinsic operator (.NOT., .AND., .OR., .EQV., .NEQV., .EQ., .NE., .GT., .GE., .LT., .LE., or .LG.) or any logical literal constant (.FALSE. or .TRUE.).
Note: The Fortran standard does not describe the .LG. operator. 
A defined operator can be the same as one of the masking or Boolean operators supported by the compiler as extensions to the Fortran standard. The corresponding operator loses its intrinsic properties. Note that the abbreviations .T., .F., .A., .O., .N., and .X. are synonyms for .TRUE., .FALSE., .AND., .OR., .NOT., and .XOR., respectively. If you define the abbreviated operator for any type, the abbreviated form of the intrinsic operator also cannot be used in any scope in which the defined operator is accessible, and the redefined abbreviated logical constants can no longer be used as logical constants.
The following examples show defined unary expressions:
Expression  Meaning  
.INVERSE. B  A defined unary expression (where .INVERSE. is a defined operator)  
A  A primary is also a defined unary expression 
An exponentiation expression is an expression in which the operator is the exponentiation operator **. This is defined as follows:
 exponentiation_expr  is 

Note that the definition is right recursive (that is, the defined term appears to the right of the operator **) which indicates that the precedence of the ** operator in contexts of equal precedence is righttoleft. Thus, the interpretation of the expression A ** B ** C is A ** ( B ** C ).
The following examples show exponentiation expressions:
Expression  Meaning  
A ** B  An exponentiation expression  
A ** B ** C  An exponentiation expression with righttoleft precedence  
.INVERSE. B  A defined unary expression is also an exponentiation expression  
A  A primary is also an exponentiation expression 
A multiplication expression is an expression in which the operator is either * or /. It is defined as follows:
 multiplication_expr  is 
 

 or 

Note that the definition is left recursive (that is, the defined term appears to the left of the operator * or /) which indicates that the precedence of the * and / operators in contexts of equal precedence is lefttoright. Thus, the interpretation of the expression A * B * C is (A * B) * C, or A / B * C is (A / B) * C. This lefttoright precedence rule applies to the remaining binary operators except the relational operators.
The following examples show multiplication expressions:
A summation expression is an expression in which the operator is either + or . It is defined as follows:
 summation_expr  is 
 

 or 

The following examples show summation expressions:
A concatenation expression is an expression in which the operator is //. It is defined as follows:
 concatenation_expr  is 

The following examples show concatenation expressions:
A comparison expression is an expression in which the operator is a relational operator. It is defined as follows:
 comparison_expr  is 
 
 rel_op  is 
 

 or 
 

 or 
 

 or 
 

 or 
 

 or 
 
EXT 
 or 
 

 or 
 

 or 
 

 or 
 

 or 
 

 or 
 

 or 
 
EXT 
 or 

The operators ==, /=, <, <=, >, >=, and <> are synonyms in all contexts for the operators .EQ., .NE., .LT., .LE., .GT., .GE., and .LG., respectively.
Note: The Fortran standard does not describe the .LG. or <> operators. 
Note that the definition of a comparison expression is not recursive, and therefore comparison expressions cannot contain relational operators in contexts of equal precedence.
The following examples show comparison expressions:
A not expression is an expression in which the operator is .NOT.. It is defined as follows:
 not_expr  is 

Note that the definition of a not expression is not recursive, and therefore not expressions cannot contain adjacent .NOT. operators.
The following examples show not expressions:
Expression  Meaning  
.NOT. A  A not expression  
A .EQ. B  A comparison expression is also a not expression  
A // B  A concatenation expression is also a not expression  
A  B  A summation expression is also a not expression  
 A  A summation expression is also a not expression  
A * B  A multiplication expression is also a not expression  
A ** B  An exponentiation expression is also a not expression  
.INVERSE. B  A defined unary expression is also a not expression  
A  A primary is also a not expression 
A conjunct expression is an expression in which the operator is .AND.. It is defined as follows:
 conjunct_expr  is 

Note that the definition of a conjunct expression is left recursive, and therefore the precedence of the .AND. operator in contexts of equal precedence is lefttoright. Thus, the interpretation of the expression A .AND. B .AND. C is (A .AND. B) .AND. C.
The following examples show conjunct expressions:
An inclusive disjunct expression is an expression in which the operator is .OR.. It is defined as follows:
 inclusive_disjunct_expr  is 

Note that the definition of an inclusive disjunct expression is left recursive, and therefore the precedence of the .OR. operator in contexts of equal precedence is lefttoright. Thus, the interpretation of the expression A. OR. B .OR. C is (A .OR. B) .OR. C.
The following examples show inclusive disjunct expressions:
Expression  Meaning  
A .OR. B  An inclusive disjunct expression  
A .OR. B .OR. C  An inclusive disjunct expression with lefttoright precedence  
A .AND. B  A conjunct expression is also an inclusive disjunct expression  
.NOT. A  A not expression is also an inclusive disjunct expression  
A .EQ. B  A comparison expression is also an inclusive disjunct expression  
A // B  A concatenation expression is also an inclusive disjunct expression  
A  B  A summation expression is also an inclusive disjunct expression  
 A  A summation expression is also an inclusive disjunct expression  
A * B  A multiplication expression is also an inclusive disjunct expression  
A ** B  An exponentiation expression is also an inclusive disjunct expression  
.INVERSE. B  A defined unary expression is also an inclusive disjunct expression  
A  A primary is also an inclusive disjunct expression 
An equivalence expression is an expression in which the operator is either .EQV. or .NEQV.. It is defined as follows:
 equivalence_expr  is 
 

 or 

An exclusive disjunct expression is an expression in which the operator is .XOR.. It is defined as follows:
EXT  exclusive_disjunct_expr  is 

Note: The Fortran standard does not specify the .XOR. operator. 
Note the following:
In the following discussion, equivalence expression means either equivalence expression or exclusive disjunct expression.
The definition of an equivalence expression is left recursive, and therefore the precedence of the .EQV. or .NEQV. operators in contexts of equal precedence is lefttoright. Thus, the interpretation of the expression A .EQV. B .NEQV. C is (A .EQV. B) .NEQV. C.
The following examples show equivalence expressions:
The most general form of an expression is defined as follows:
 expr  is 
 
 defined_binary_op  is 

Note that the definition of an expression is left recursive, and therefore the precedence of the binary defined operator in contexts of equal precedence is lefttoright. The interpretation of the expression A .PLUS. B .MINUS. C is thus (A .PLUS. B) .MINUS. C (where .MINUS. is a defined operator).
The following examples show expressions:
The previous sections have described in detail the sorts of expressions that can be formed. These expressions form a hierarchy that can best be illustrated by a figure. Figure 71, describes the hierarchy by placing the simplest form of an expression, a variable, at the center of a set of nested rectangles. The more general forms of an expression are the enclosing rectangles, from a primary to an exponentiation expression, to a summation expression, and finally to a general expression using a defined binary operator .CROSS.. Figure 71 demonstrates that an expression is all of these special case forms, including the simplest form, a primary.
Table 72, illustrates the relationship between the different sorts of expressions by summarizing the definitional forms in one table. The simplest form of an expression is at the bottom and is the primary, as in Figure 71. The next, more general, form is second from the bottom and is the defined unary expression; it uses the primary in its definition. At the top of the table is the most general form of an expression.
Table 73 summarizes the relative precedence of operators, including the precedence when operators of equal precedence are adjacent. An entry of N/A in the rightmost column indicates that the operator cannot appear in such contexts. The leftmost column classifies the operators as defined, numeric, character, relational, and logical operators. Note that these operators are not intrinsic operators unless the types of the operands are those specified in Table 74.
Table 73. Categories of operations and relative precedences
Category of operator  Operator  Precedence  In context of equal precedence 

Defined  Unary definedoperator  Highest  N/A 
Numeric  **  .  Righttoleft 
Numeric  * or /  .  Lefttoright 
Numeric  Unary + or   .  N/A 
Numeric  Binary + or   .  Lefttoright 
Character  //  .  Lefttoright 
Relational  .EQ., .NE., .LT., .LE., .GT., .GE., .LG., ==, /=, <, <=, >, >=, <>  .  N/A 
Logical or Boolean  .NOT.  .  N/A 
Logical or Boolean  .AND.  .  Lefttoright 
Logical or Boolean  .OR.  .  Lefttoright 
Logical  .EQV. or .NEQV.  .  Lefttoright 
Logical or Boolean  .XOR.  .  Lefttoright 
Defined  Binary definedoperator  Lowest  Lefttoright 
For example, consider the following expression:
A .AND. B .AND. C .OR. D 
Table 72, indicates that the .AND. operator is of higher precedence than the .OR. operator, and the .AND. operators are combined lefttoright when in contexts of equal precedence; thus, A and B are combined by the .AND. operator, the result A .AND. B is combined with C using the .AND. operator, and that result is combined with D using the .OR. operator. Thus, this expression is interpreted the same way as the following fully parenthesized expression:
(((A .AND. B) .AND. C) .OR. D) 
Notice that the defined operators have fixed precedences; defined unary operators have the highest precedence of all operators and are all of equal precedence; defined binary operators have the lowest precedence, are all of equal precedence, and are combined lefttoright when in contexts of equal precedence. Both kinds of defined operators may have multiple definitions in the program unit and therefore may be generic just as intrinsic operators and intrinsic procedures are generic.
As a consequence of the expression formation rules, unary operators cannot appear in a context of equal precedence; the precedence must be specified by parentheses. There is thus no lefttoright or righttoleft rule for any unary operators. Similarly, the relational operators cannot appear in a context of equal precedence; consequently, there is no lefttoright or righttoleft rule for the relational operators. Use of some of the operators as Boolean or masking operators is an extension to the Fortran standard that is supported by the compiler.
Note: The Fortran standard does not specify the use of operators as Boolean or masking operators. 
Intrinsic operations are those known to the processor. For an operation to be intrinsic, an intrinsic operator symbol must be used, and the operands must be of the intrinsic types specified in Table 74.
Note: : In the following table, the symbols I, R, Z, C, L, B, and P stand for the types integer, real, complex, character, logical, Boolean, and Cray pointer, respectively. Where more than one type for x_{2} is given, the type of the result of the operation is given in the same relative position in the next column. Boolean and Cray pointer types are compiler extensions. 
Table 74. Operand types and results for intrinsic operations
Intrinsic operator  Type of x_{1}  Type of x_{2}  Type of result 

Unary +,  
 I, R, Z, B, P  I, R, Z, I, P 
Binary +, , *, /, **  I  I, R, Z, B, P  I, R, Z, I, P 
 R  I, R, Z, B  R, R, Z, R 
 Z  I, R, Z  Z, Z, Z 
 B  I, R, B, P  I, R, B, P 
 P  I, B, P  P, P, P 
 (For Cray pointer, only + and  are allowed.) 


//  C  C  C 
.EQ., ==, .NE., /=  I  I, R, Z, B, P  L, L, L, L, L 
 R  I, R, Z, B, P  L, L, L, L, L 
 Z  I, R, Z, B, P  L, L, L, L, L 
 B  I, R, Z, B, P  L, L, L, L, L 
 P  I, R, Z, B, P  L, L, L, L, L 
 C  C  L 
.GT., >, .GE., >=, .LT., <, .LE., <=  I  I, R, B, P  L, L, L, L 
 R  I, R, B  L, L, L 
 C  C  L 
 P  I, P  L, L 
.LG., <>  R  R  L 
.NOT. 
 L  L 

 I, R, B  B 
.AND., .OR., .EQV., .NEQV., .XOR.  L  L  L 
 I, R, B  I, R, B  B 
Note: The Fortran standard does not specify the use of type Boolean or the use of type Boolean in masking expressions, nor does it describe the .LG. and <> operators. 
The intrinsic operations are either binary or unary. The binary operations use the binary intrinsic operator symbols +, , *, /, **, //, .EQ., .NE., .LT., .GT., .LE., .GE., and .LG.(and their synonyms ==, /=, <>, <, >=, and <>), .AND., .OR., .XOR., .EQV., and .NEQV.. The unary operations use the unary intrinsic operator symbols +, , and .NOT..
Note that the intrinsic operators .AND., .OR., .NOT., and .XOR. can be abbreviated as .A., .O., .N., or .X.. If a userdefined operator with the same name as the abbreviated name is accessible in a scope, the abbreviated forms of these operators may not be used as synonyms for .AND., .OR., .NOT., or .XOR..
The intrinsic operations are divided into five classes with different rules and restrictions for the types of the operands. The five classes are numeric intrinsic, character intrinsic, logical intrinsic, relational intrinsic operations, and bitwise masking expressions.
The numeric intrinsic operations use the intrinsic operators +, , *, /, and **. The operands can be of any numeric type and with any kind type parameters. The result of the operation is of a type specified by Table 74, and has type parameters as specified in Section 7.2.8.2.
For example, the following expressions, in which I, R, D, and Z are declared to be of types integer, real, doubleprecision real, and complex, have the types and type parameters of the variables R, I, D, and Z, respectively:
I + R I * I I  D I / Z 
There is only one character intrinsic operation; it uses the intrinsic operator //. The result of a character intrinsic operation is type character.
The logical intrinsic operations use the intrinsic operators .AND., .OR., .NOT., .EQV., and .NEQV., respectively. The result of a logical intrinsic operation is type logical and has type parameters as specified in Section 7.2.8.2.
The relational intrinsic operations use the intrinsic operators .EQ., .NE., .GT., .GE., .LT., .LE., or .LG. or their symbolic synonyms. A relational intrinsic operation is a numeric relational intrinsic operation if its operands are of type integer, real, or complex. A relational intrinsic operation is a character relational intrinsic operation if its operands are of type character. The result of either kind of relational operation is type logical and has type parameters as specified in Section 7.2.8.2.
Note: The Fortran standard does not describe the .LG. operator. 
The operators .NOT., .AND., .OR., .EQV., and .XOR. can also be used in the compiler's bitwise masking expressions; these are extensions to the Fortran standard. The result is type integer.
A defined operation is any nonintrinsic operation that is interpreted and evaluated by a function subprogram specified by an interface block with a generic specifier of the following form:
OPERATOR (defined_operator) 
A defined elemental operation is a defined operation for which the function is elemental.
A defined operation uses either a defined operator or an intrinsic operator symbol, and it is either unary or binary. Its forms are as follows:

The terms intrinsic_unary_op and intrinsic_binary_op include all intrinsically defined operators; these terms are not specifically defined in any syntax rules.
x_{1} and x_{2} are operands. When an intrinsic operator symbol is used, the type of x_{2} (for a unary operator) and types of x_{1} and x_{2} (for a binary operator) must not be the same as the types of the operands specified in Table 74, for the particular intrinsic operator symbol. Thus, you cannot redefine intrinsic operations on intrinsic types.
When a defined operation uses an intrinsic operator symbol, the generic properties of that operator are extended to the new types specified by the interface block. When a defined operation uses a defined operator, the defined operation is called an extension operation, and the operator is called an extension operator. An extension operator can have generic properties by specifying more than one function subprogram in an interface block with a generic specifier of the form OPERATOR (defined_operator).
The data type, type parameters, and shape of a complete expression are determined by the data type, type parameters, and shape of each constant, variable, constructor, and function reference appearing in the expression. The determination is insideout in the sense that the properties are determined first for the primaries. These properties are then determined repeatedly for the operations in precedence order, resulting eventually in the properties for the expression.
For example, consider the expression A + B * C, where A, B, and C are of numeric type. First, the data types, type parameter values, and shapes of the three variables A, B, and C are determined. Because * has a higher precedence than +, the operation B * C is performed first. The type, type parameters, and shape of the expression B * C are determined next, and then these properties for the entire expression are determined from those of A and B * C.
A defined elemental operation is a defined operation for which the function is elemental.
The type, type parameters, and shape of a primary that is a nonpointer variable or constant are straightforward because these properties are determined by specification statements for the variable or named constant, or by the form of the constant. For example, if A is a variable, its declaration in a specification statement such as the following determines it as an explicitshaped array of type real with a default kind parameter:
REAL A(10, 10) 
For a constant such as the following, the form of the constant indicates that it is a scalar constant of type complex and of default kind:
(1.3, 2.9) 
For a pointer variable, the type, type parameters, and rank are determined by the declaration of the pointer variable. However, if the pointer is of deferred shape, the shape (in particular, the extents in each dimension) is determined by the target of the pointer. Consider the following declarations and assume that pointer A is associated with the target B:
REAL, POINTER :: A(:, :) REAL, TARGET :: B(10, 20) 
The shape of A is (10, 20).
The type and type parameters of an array constructor are determined by the contents of the constructor. Unless the element is of type Boolean (typeless), its type and type parameters are those of any element of the constructor because they must all be of the same type and type parameters. If the element is of type Boolean, the type and kind type of the array constructor are the same as the default integer type. Therefore, the type and type parameters of the following array constructor are integer and kind value 1:
(/ 1_1, 123_1, 10_1 /) 
Its shape is always of rank one and of size equal to the number of elements.
The type of a structure constructor is the derived type used as the name of the constructor. A structure has no type parameters. So, the type of the following structure constructor is the derived type PERSON:
PERSON(56, 'Father') 
(See Section 4.6 in Chapter 4, for the type definition PERSON.)
A structure constructor is always a scalar.
The type, type parameters, and shape of a function are determined by one of the following:
An implicit type declaration for the function within the program unit referencing the function
An explicit type declaration for the function within the program unit referencing the function (just like a variable)
An explicit interface to the function. (When the interface is not explicit, the function is either an external function or a statement function.)
If the interface is explicit, the type, type parameter, and shape are determined by one of the following:
The type and other specification statements for the function in an interface block within the program unit referencing the function
The type and other specification statements for the internal or module procedure specifying the function
The description of the particular intrinsic function being referenced
Note, however, that because intrinsic functions and functions with interface blocks can be generic, these properties are determined by the type, type parameters, and shapes of the actual arguments of the particular function reference.
For example, consider the following statements as part of the program unit specifying an internal function FCN:
REAL FUNCTION FCN(X) DIMENSION FCN(10, 15) 
A reference to FCN(3.3) is of type default real with shape (10,15). As a second example, consider the following:
REAL(SINGLE) X(10, 10, 10) . . . . . . SIN(X) . . . 
The interface to SIN(3i) is specified by the definition of the sine intrinsic function. In this case, the function reference SIN(X) is of type real with kind parameter value SINGLE and of shape (10,10,10).
The interface is implicit if the function is external (and no interface block is provided) or is a statement function. In these cases, the shape is always that of a scalar, and the type and type parameters are determined by the implicit type declaration rules in effect, or by an explicit type declaration for the function name. In the following example, FCN(X) is a scalar of type integer with kind type parameter value SHORT:
IMPLICIT INTEGER(SHORT) (AF) . . . . . . FCN(X) . . . 
The one case for variables and functions that is not straightforward is the determination of the shape of a variable when it is of deferred shape or of assumed shape. For a deferredshape array, the rank is known from the declaration but the size of each dimension is determined as the result of executing an ALLOCATE statement or a pointer assignment statement. For an assumedshape array, the rank is also known from the declaration but the size is determined by information passed into the subprogram. In the case of pointers, the shape of the object is that of the target associated with (pointed to by) the pointer. The shape of deferredshape and assumedshape arrays thus cannot be determined in general until execution time.
The type of the result of an intrinsic operation is determined by the type of the operands and the intrinsic operation and is specified by Table 74.
For nonnumeric operations, the type parameters of the result of an operation are determined as follows:
For the relational intrinsic operations, the kind type parameter is that for the default logical type.
For logical intrinsic operations, the result kind type parameter depends on that of the operands. If the operands have the same kind type parameter (that is the same value for KIND=value), the kind type parameter is that of the operands. If logical operands have different kind type parameter values, the value of the result is that of the greater kind type parameter value.
For the character intrinsic operation (//), the operands must have the same kind type parameter, so the result has that kind type parameter.
The character length parameter value for the result is the sum of the character length parameters of the operands.
For numeric intrinsic operations, the kind type parameter value of the result is determined as follows:
For unary operations, the kind type parameter value of the result is that of the operand.
Floatingpoint operands are those of type real or type complex. If an operation includes a floatingpoint operand and an integer, the result type and kind type parameter value is determined as follows:
The result type is that of the floatingpoint operand.
The result kind type parameter value is the same as the kind type parameter value of the floatingpoint operand.
See Table 74, for more information.
If an operation includes operands of type complex and type real, the result type and kind type parameter value is determined as follows:
The result type is type complex.
The result kind type parameter value is that of the greater value. That is, the kind type parameter value of each operand is examined, and whichever kind type parameter value is greater is assigned to the result.
See Table 74, for more information.
For binary operations, if the operands are of the same type and kind type parameters, the kind type parameter value of the result is the kind type parameter of the operands.
For binary operations, if the operands are both of type integer but with different kind type parameters, the kind type parameter value of the result is the kind type parameter of the operand with the larger decimal exponent range. If the decimal exponent ranges of the two kinds are the same, the kind type parameter value of the result is the same as each operand.
For binary operations, if the operands are both of type real or complex but with different kind type parameters, the kind type parameter of the result is the kind type parameter of the operand with the larger decimal precision. If the decimal precisions are the same, the kind type parameter value is that of the operands.
For numeric intrinsic operations, an easy way to remember the result type and type parameter rules is to consider that the numeric types (integer; real; complex; and compiler Boolean) are ordered by the increasing generality of numbers. Integers are contained in the set of real numbers and real numbers are contained in the set of complex numbers. Within the integer type, the kinds are ordered by increasing value ranges. Within the real and complex types, the kinds for each type are ordered by increasing decimal precision.
Using this model, the result type of a numeric intrinsic operation is the same type as the operand of the greater generality. For the result type parameter, the rule is complicated: if one or both of the operands is of type real or complex, the type parameter is that of the set of numbers of the more general type described above and with a precision as large as the precision of the operands; if both are of type integer, the result type parameter is of a set of numbers that has a range as large as the range of the operands.
The type and type parameter values of a defined operation are determined by the interface block for the referenced operation and are the type and type parameters of the name of the function specified by the interface block. Note that the operator can be generic and therefore the type and type parameters can be determined by the operands. For example, consider the following interface:
INTERFACE OPERATOR (.PLUS.) TYPE(SET) FCN_SET_PLUS(X, Y) USE DEFINITIONS TYPE (SET) X, Y INTENT(IN) X, Y END FUNCTION FCN_SET_PLUS TYPE(RATIONAL) FCN_RAT_PLUS(X, Y) USE DEFINITIONS TYPE(RATIONAL) X, Y INTENT(IN) X, Y END FUNCTION FCN_RAT_PLUS END INTERFACE 
The operation A .PLUS. B, where A and B are of type RATIONAL, is an expression of type RATIONAL with no type parameters. The operation C .PLUS. D, where C and D are of type SET is an expression of type SET with no type parameters.
The shape of an expression is determined by the shape of each operand in the expression in the same recursive manner as for the type and type parameters for an expression. That is, the shape of an expression is the shape of the result of the last operation determined by the interpretation of the expression.
However, the shape rules are simplified considerably by the requirement that the operands of binary intrinsic operations must be in shape conformance; two operands are in shape conformance if both are arrays of the same shape, or one or both operands are scalars. The operands of a defined operation have no such requirement but must match the shape of the corresponding dummy arguments of the defining function.
For primaries that are constants, variables, constructors, or functions, the shape is that of the constant, variable, constructor, or function name. Recall that structure constructors are always scalar, and array constructors are always rankone arrays of size equal to the number of elements in the constructor. For unary intrinsic operations, the shape of the result is that of the operand. For binary intrinsic operations, the shape is that of the array operand if there is one and is scalar otherwise. For defined operations, the shape is that of the function name specifying the operation.
For example, consider the intrinsic operation A + B where A and B are of type default integer and default real respectively; assume A is a scalar and B is an array of shape (3, 5). Then, the result is of type default real with shape (3, 5).
For most contexts, the lower and upper bounds of an array expression are not needed; only the sizes of each dimension are needed to satisfy array conformance requirements for expressions. The bounds of an array expression when it is the ARRAY argument (first positional argument) of the LBOUND(3i) and UBOUND(3i) intrinsic functions are needed, however.
The functions LBOUND(3i) and UBOUND(3i) have two keyword arguments ARRAY and DIM. ARRAY is an array expression and DIM, which is optional, is an integer. If the DIM argument is present, LBOUND(3i) and UBOUND(3i) return the lower and upper bounds, respectively, of the dimension specified by the DIM argument. If DIM is absent, they return a rankone array of the lower and upper bounds, respectively, of all dimensions of the ARRAY argument. As described below, these functions distinguish the special cases when the array argument is a name or structure component with no section subscript list from the general case when the array argument is a more general expression. Note that if A is a structure with an array component B, A%B is treated as if it were an array name and not an expression.
When the ARRAY argument is an array expression that is not a name or a structure component, the function LBOUND(3i) returns 1 if the DIM argument is specified and returns a rankone array of 1s if the DIM argument is absent. For the same conditions, the function UBOUND(3i) returns as the upper bound the size of the requested dimension or the size of all dimensions in a rankone array.
When the ARRAY argument is an array name or a structure component with no section subscript list, there are four cases to distinguish depending on the array specifier for the name. The following sections describe these four cases.
The LBOUND(3i) and UBOUND(3i) functions return the declared lower and upper bounds of the array name or the structure component with no section subscript list.
INTEGER A(2:10, 11:12) . . . TYPE PASSENGER_INFO INTEGER NUMBER INTEGER TICKET_IDS(2:500) END TYPE PASSENGER_INFO . . . TYPE(PASSENGER_INFO) PAL, MANY(3:10) 
In this example, LBOUND(A) has the value (/ 2, 11 /), and UBOUND(A, 1) has the value 10. LBOUND(PAL%TICKET_IDS) has the value (/ 2 /) and UBOUND(MANY%TICKET_IDS(2), 1) has the value 10.
The name is a dummy argument whose extents are determined by the corresponding actual argument. The dummy argument may have its lower bound in a particular dimension specified but if not, the lower bound is defined to be 1. The LBOUND(3i) function returns these lower bounds. The upper bound for a particular dimension is the extent of the actual argument in that dimension, if no lower bound is specified for the dummy argument. It is the extent minus 1 plus the lower bound if a lower bound is specified. The UBOUND(3i) function returns these upper bounds.
REAL C(2:10, 11:12) . . . CALL S(C(4:8, 7:9)) CONTAINS SUBROUTINE S(A) REAL A(:, 2:) . . . ! Reference to LBOUND(A) and UBOUND(A) . . . 
Inside the body of subroutine S, LBOUND(A) has the value (/ 1, 2 /), because the array starts at subscript position 1 by default in the first dimension and starts at subscript position 2 by declaration in the second dimension. UBOUND(A) has the value (/ 5, 4 /), because there are five subscript positions (4 to 8) in the first dimension of the actual argument corresponding to A, and three subscript positions (7 to 9) in the second dimension of the same actual argument and the subscripts are specified to start at 2 by the declaration of the dummy argument A.
The name is a dummy argument whose upper and lower bounds in all but the last dimension are declared for the dummy argument. The lower bound for the last dimension may be specified in the assumedsize specifier but, if absent, the lower bound is 1. The LBOUND(3i) function returns these lower bounds. The upper bound for all dimensions except the last one is known to the subprogram but the upper bound in the last dimension is not known. The UBOUND(3i) function, therefore, must not be referenced with the first argument being the name of an assumedsize array and no second argument, or the first argument being the name of an assumedsize array and the second argument specifying the last dimension of the array. Otherwise, the UBOUND(3i) function returns the upper bounds as declared for all but the last dimension.
REAL C(2:10, 11:12) . . . CALL S (C(4:8, 7:9)) CONTAINS SUBROUTINE S (A) REAL A(2:2, *) . . . ! Reference to LBOUND(A, 1) and UBOUND(A(:, 2)) ! A reference to UBOUND(A) would be illegal. ! A reference to UBOUND(A, 2) would be illegal. . . . 
Inside the body of subroutine S, LBOUND(A, 1) has the value 2. UBOUND(A(:, 2)) has the value 5 because A(:,2) is an expression, which is an array section, not an array name, and has five elements in the first dimension.
The name is the name of an allocatable array, an array pointer, or a structure component with one of its part references being a pointer array. As such, if the array or a part reference has not been allocated or associated with a target, the LBOUND(3i) and UBOUND(3i) functions must not be invoked with the ARRAY argument equal to such an array name. If it is an array pointer, either its target has been allocated by an ALLOCATE statement or its target has become associated with the pointer using a pointer assignment statement. In the former case, the LBOUND(3i) and UBOUND(3i) functions return the lower and upper bounds specified in the ALLOCATE statement. In the latter case, LBOUND is always 1 in pointer assignment, and UBOUND is the extent of the dimension. Note that for zerosized dimensions, LBOUND is always 1 and UBOUND is always 0.
REAL, ALLOCATABLE :: A(:, :) . . . ALLOCATE ( A(5, 7:9) ) . . .! Reference to LBOUND(A) and UBOUND(A) . . . 
After the ALLOCATE statement above is executed, LBOUND(A) has the value (/ 1, 7 /), and UBOUND(A) has the value (/ 5, 9 /).
Expressions can appear in statements other than assignment statements, in particular in specification statements. In many cases, such expressions are restricted in some way; for example, the operands in expressions in a PARAMETER statement are essentially restricted to constants. The standard and this manual use specific terms for the various categories of expressions allowed in specific syntactic contexts. For example, the expressions that can be used in PARAMETER statements are called initialization expressions and can be evaluated at the time the program is compiled. Initialization expressions are restricted forms of constant expressions.
The expressions that can be used as array bounds and character lengths in specification statements are called specification expressions. These expressions are scalar and of type integer and can be evaluated on entry to the program unit at the time of execution. The remainder of this subsection describes and defines such limited expressions and summarizes where they can be used.
A constant expression is one of the following constant values or is an expression consisting of intrinsic operators whose operands are any of the following constant values:
A literal or named constant, or a subobject of a constant where each subscript, section subscript, or starting and ending point of a substring range is a constant expression.
An array constructor where every subexpression has primaries that are constant expressions or are impliedDO variables of the array constructor.
A structure constructor where each component is a constant expression.
An elemental intrinsic function reference that can be evaluated at compile time.
A transformational intrinsic function reference that can be evaluated at compile time.
A reference to NULL(3i).
A reference to an intrinsic function that is one of the following:
An array inquiry function other than ALLOCATED(3i)
The bit inquiry function BIT_SIZE(3i)
The character inquiry function LEN(3i)
The KIND(3i) inquiry function
A numeric inquiry function
Each argument of the function must be a constant expression or must be a variable whose type parameters or bounds inquired about are not assumed, defined by an expression that is not a constant expression, or definable by an ALLOCATE or pointer assignment statement.
An impliedDO variable within an array constructor in which the bounds and strides of the corresponding impliedDO are constant expressions.
A constant expression enclosed in parentheses.
The restriction in item 4 to intrinsic functions that can be evaluated at compiletime eliminates the use of the intrinsic functions PRESENT(3i), ALLOCATED(3i), and ASSOCIATED(3i). It also requires that each argument of the intrinsic function reference be a constant expression or a variable whose type parameters or bounds are known at compile time. This restriction excludes, for example, named variables that are assumedshape arrays, assumedsize arrays for inquiries requiring the size of the last dimension, and variables that are pointer arrays or allocatable arrays. For example, if an array X has explicit bounds in all dimensions, an inquiry such as SIZE(X) can be computed at compiletime, and SIZE(X) + 10 is considered a constant expression.
Constant expressions can be used in any executable statement where general expressions (that is, unrestricted expressions) are permitted.
The following examples show constant expressions:
Expression  Meaning 
2  An integer literal constant 
7.5_LARGE  A real literal constant where LARGE is a named integer constant 
(/ 7, (I, I = 1, 10) /)  An array constructor 
RATIONAL(1, 2+J)  A structure constructor where RATIONAL is a derived type and J is a named integer constant 
LBOUND(A,1)+3  A reference to an inquiry intrinsic function where A is an explicitshape array 
INT(N)  An intrinsic function reference where N is a named constant 
KIND(X)  An intrinsic function reference where X is a real variable with known type parameter 
REAL(10+I)  An intrinsic function reference where I is a named integer constant 
COUNT(A)  An intrinsic function where A is a named logical constant 
I/3.3 + J**3.3  A numeric expression where I and J are named integer constants 
SUM(A)  A reference to a transformational intrinsic function where A is a named integer array constant 
An initialization expression is a constant expression restricted as follows:
The exponentiation operator (**) is allowed only when the power (second operand) is of type integer; that is, X ** Y is allowed only if Y is of type integer.
Subscripts, section subscripts, starting and ending points of substring ranges, components of structure constructors, and arguments of intrinsic functions must be initialization expressions.
The elements of array constructors must be initialization expressions or impliedDOs for which the array constructor values and impliedDO parameters are expressions whose primaries are initialization expressions or impliedDO variables.
An elemental intrinsic function in an initialization expression must have arguments that are initialization expressions and are of type integer or character. These elemental intrinsic functions must return a result of type integer or character.
A transformational intrinsic function in an initialization expression must be one of the intrinsic functions NULL(3i), REPEAT(3i), RESHAPE(3i), SELECTED_INT_KIND(3i), SELECTED_REAL_KIND(3i), TRANSFER(3i), and TRIM(3i), and must have initialization expressions as arguments; this excludes the use of the transformational functions ALL(3i), ANY(3i), COUNT(3i), CSHIFT(3i), DOT_PRODUCT(3i), EOSHIFT(3i), MATMUL(3i), MAXLOC(3i), MAXVAL(3i), MINLOC(3i), MINVAL(3i), PACK(3i), PRODUCT(3i), SPREAD(3i), SUM(3i), TRANSPOSE(3i), and UNPACK(3i).
An inquiry intrinsic function is allowed, except that the arguments must either be initialization expressions or variables whose type parameters or bounds inquired about are not assumed, not defined by an ALLOCATE statement, or not defined by pointer assignment.
Any subexpression enclosed in parentheses must be an initialization expression.
All but the last examples in Section 7.2.9.1, are initialization expressions. The last are not because initialization expressions cannot contain functions that return results of type real (REAL(3i), LOG(3i)), must not reference certain transformational functions (COUNT(3i), SUM(3i)), or cannot use the exponentiation operator when the second operand is of type real.
The following are examples of initialization expressions:
Expression  Meaning 
SIZE(A, 1) * 4  An integer expression where A is an array with an explicit shape 
KIND(0.0D0)  An inquiry function with a constant argument 
SELECTED_REAL_KIND(6, 30)  An inquiry function with constant arguments 
SELECTED_INT_KIND(2 * R)  An inquiry function with an argument that is an initialization expression, where R is a previously declared named constant of type integer 
Initialization expressions must be used in the following contexts:
As initial values following the equal signs in PARAMETER statements and in type declaration statements with the PARAMETER attribute.
As initial values following the equal signs in type declaration statements for variables.
As expressions in structure constructors in DATA statement value lists.
As expressions in default initializers.
As kind type parameter values in type declaration statements; in this case, they also must be scalar and of type integer.
As actual arguments for the KIND(3i) dummy argument of the conversion intrinsic functions AINT(3i), ANINT(3i), CHAR(3i), INT(3i), LOGICAL(3i), NINT(3i), REAL(3i), CMPLX(3i); in this case, they also must be scalar and of type integer.
As case values in the CASE statement; in this situation, they must be scalar and of type integer, logical, or character.
As subscript or substring range expressions of equivalence objects in an EQUIVALENCE statement; in this case, they must be scalar and of type integer.
Initialization expressions must be used for situations where the value of the expression is needed at compile time. Note that the initialization expressions do not include intrinsic functions that return values of type real, logical, or complex, or have arguments of type real, logical, or complex.
A specification expression is a restricted expression that has a scalar value and is of type integer. Specification expressions are used as bounds for arrays and length parameter values for character entities in type declarations, attribute specifications, dimension declarations, and other specification statements (see Table 75). A constant specification expression is a specification expression that is also a constant.
Specification expressions are forms of restricted expressions (defined below), limited in type and rank. Briefly, a restricted expression is limited to constants and certain variables accessible to the scoping unit whose values can be determined on entry to the program unit before any executable statement is executed. For example, variables that are dummy arguments, are in a common block, are in a host program unit, or are in a module made accessible to the program unit can be evaluated on entry to a program unit. Array constructors, structure constructors, intrinsic function references, and parenthesized expressions made up of these primaries must depend only on restricted expressions as building blocks for operands in a restricted expression.
A restricted expression is an expression in which each operation is intrinsic and each primary is limited to one of the following:
A constant or constant subobject.
A variable that is a dummy argument with neither the OPTIONAL nor the INTENT(OUT) attribute.
A variable that is in a common block.
A variable made accessible from a module.
A variable from the host program unit.
A variable accessible through USE association.
An array constructor in which every expression has primaries that are restricted expressions or are impliedDO variables of the array constructor.
A structure constructor in which each component is a restricted expression.
An elemental intrinsic function whose result is of type integer or character and whose arguments are all restricted expressions of type integer or character.
One of the transformational intrinsic functions (REPEAT(3i), RESHAPE(3i), SELECTED_INT_KIND(3i), SELECTED_REAL_KIND(3i), TRANSFER(3i), or TRIM(3i)), in which each argument is a restricted expression of type integer or character (this excludes the use of the transformational functions ALL(3i), ANY(3i), COUNT(3i), CSHIFT(3i), DOT_PRODUCT(3i), EOSHIFT(3i), MATMUL(3i), MAXLOC(3i), MAXVAL(3i), MINLOC(3i), MINVAL(3i), PACK(3i), PRODUCT(3i), SPREAD(3i), SUM(3i), TRANSPOSE(3i), and UNPACK(3i)).
An inquiry intrinsic function (except for PRESENT(3i), ALLOCATED(3i), and ASSOCIATED(3i)), in which each argument is one of the following:
A restricted expression. Any subscript, section subscript, and starting or ending point of a substring range is a restricted expression.
A variable whose bounds or type parameters inquired about are not assumed, not defined by an ALLOCATE statement, and not defined by a pointer assignment statement
A reference to any other intrinsic function in which each argument is a restricted expression.
A reference to an external function whose result is a nonpointer scalar intrinsic type.
A reference to a specification function in which each argument is a restricted expression.
A function is a specification function if it is a pure function, is not an intrinsic function, is not an internal function, is not a statement function, does not have a dummy procedure argument, and is not RECURSIVE.
Note: The Fortran standard does not specify restricted expressions in which a primary can be a reference to an external function that is not a specification function and with a result that is a nonpointer scalar intrinsic type. 
The following rules and restrictions apply to the use of initialization and specification expressions in specification statements.
The type and type parameters of a variable or named constant in one of these expressions must be specified in a prior specification in the same scoping unit, in a host scoping unit, in a module scoping unit made accessible to the current scoping unit, or by the implicit typing rules in effect. If the variable or named constant is explicitly given these attributes in a subsequent type declaration statement, it must confirm the implicit type and type parameters.
If an element of an array is referenced in one of these expressions, the array bounds must be specified in a prior specification.
If a specification expression includes a variable that provides a value within the expression, the expression must appear within the specification part of a subprogram. For example, consider variable N in the following program segment:
INTEGER N COMMON N REAL A (N) 
N is providing a value that determines the size of the array A. This program segment must not appear in a main program but may appear in the specification part of a subprogram.
A prior specification in the above cases may be in the same specification statement, but to the left of the reference. For example, the following declarations are valid:
INTEGER, DIMENSION(4), PARAMETER :: A = (/4, 3, 2, 1 /) REAL, DIMENSION(A (2)) :: B, C(SIZE(B)) 
B and C are of size 3 (the second element of the array A). The following declaration, however, is invalid because SIZE(E) precedes E:
REAL, DIMENSION(2) :: D(SIZE(E)), E 
The various kinds of expressions may be somewhat confusing, and it can be difficult to remember where they can be used. To summarize the differences, Section 7.2.4, specifies the most general kind of expression; the other kinds of expressions are restrictions of the most general kind. The classification of expressions forms two orderings, each from most general to least general, as follows:
Expression, restricted expression, and specification expression
Expression, constant expression, and initialization expression
The relationship between the various kinds of expression can be seen in the diagram in Figure 72.
Initialization expressions are not a subset of specification expressions because the result of an initialization expression can be of any type, whereas the result of a specification expression must be of type integer and scalar. Also, specification expressions are not a subset of initialization expressions because specification expressions allow certain variables (such as dummy arguments and variables in common blocks) to be primaries, where as initialization expressions do not allow such variables.
Table 75, describes the differences between initialization and specification expressions. Table 76, summarizes where each kind of expression is used and gives the restrictions as to their type and rank when used in the various contexts. For example, Table 75, indicates that initialization and specification expressions are different in that initialization expressions can be array valued, whereas specification expressions are scalar. A consequence of this difference, as indicated in Table 76, is that an initialization expression is used in a type declaration statement or a PARAMETER statement to specify the value of a named constant array, whereas a specification expression is used to specify the bounds of an array in a declaration statement.
Table 75. Differences and similarities between initialization and specification expressions
Kind of expression:  

Property:  Initialization  Specification 
Character result  Yes  No^{[a]} 
Integer result  Yes  Yes 
Scalar result  Yes  Yes 
Array result  Yes  No 
Variables as primaries(limited to dummy arguments, common block objects, host objects, module objects)  No  Yes 
Elemental intrinsic functions of type integer and character as primaries  Yes  Yes 
Elemental intrinsic functions of type real, complex, logical, and derived type as primaries  No  No 
Only constants as primaries  Yes  No 
Only constant subscripts, strides, character lengths  Yes  No 
One of the transformational intrinsic functions REPEAT, RESHAPE, SELECTED_INT_KIND, SELECTED_REAL_KIND, TRANSFER, or TRIM as primaries  Yes  Yes 
Inquiry intrinsic functions (not including ALLOCATED, ASSOCIATED, or PRESENT) as primaries  Yes  Yes 
Reference to specific functions  No  Yes 
Reference to scalar external function with intrinsic type result that is not a specification function ^{[b]}  No  Yes 
^{[a] }Expression results of type character are allowed if they are arguments of an intrinsic function. ^{[b] }This is an extension to the Fortran standard. 
Table 76. Kinds of expressions and their uses
Context  Arb. expr.  Init. expr.  Spec. expr.  Type ^{[a]}  Rank ^{[b]} 

Default integer expression  
Bounds in declaration statement ^{[c]}  No  No  Yes  I  Scalar 
Lengths in declaration statement ^{[d]}  No  No  Yes  I  Scalar 
Subscripts and substring ranges in EQUIVALENCE statement  No  Yes  No  I  Scalar 
Values in CASE statement  No  Yes  No  I,L,C  Scalar 
Kind parameters in declaration statement  No  Yes  No  I  Scalar 
Kind arguments in intrinsics  No  Yes  No  I  Scalar 
Initial value in PARAMETER and type declaration statement  No  Yes  No  Any  Any 
DATA impliedDO parameters  No  ^{[e]}  No  I  Scalar 
Assignment  Yes  Yes  Yes  Any  Any 
Subscripts in executable statement  Yes  Yes  Yes  I  ≤1 
Strides in executable statement  Yes  Yes  Yes  I  Scalar 
Substring ranges in executable statement  Yes  Yes  Yes  I  Scalar 
Expression in SELECT CASE  Yes  Yes  Yes  I,L,C  Scalar 
IF statement  Yes  Yes  Yes  L  Scalar 
Arithmetic IF statement  Yes  Yes  Yes  I,R  Scalar 
DO statement  Yes  Yes  Yes  I,R  Scalar 
Mask in WHERE statement  Yes  Yes  Yes  L  Array 
Mask in WHERE construct  Yes  Yes  Yes  L  Array 
IFTHEN statement  Yes  Yes  Yes  L  Scalar 
ELSEIF statement  Yes  Yes  Yes  L  Scalar 
Output item list  Yes  Yes  Yes  Any  Any 
I/O specifier values except character FMT= specifier ^{[f]}  Yes  Yes  Yes  I,C  Scalar 
I/O FMT= specifier value  Yes  Yes  Yes  C  Any 
RETURN statement  Yes  Yes  Yes  I  Scalar 
Computed GO TO statement  Yes  Yes  Yes  I  Scalar 
Array constructor impliedDO parameters  Yes  Yes  Yes  I  Scalar 
Actual arguments  Yes  Yes  Yes  Any  Any 
I/O impliedDO parameters  Yes  Yes  Yes  I,R  Scalar 
FORALL triplet_spec_list  Yes  Yes  Yes  I  Scalar 
FORALL scalar_mask  Yes  Yes  Yes  L  Scalar 
Expressions in statement function definitions  Yes  Yes  Yes  Any  Scalar 
^{[a] }"Any" in this column means any intrinsic or derived type. ^{[b] }"Any" in this column means that the result may be a scalar or an array of any rank. ^{[c] }The relevant declaration statements are type declaration, component definition, DIMENSION , TARGET , and COMMON statements. ^{[d] }The relevant declaration statements are type declaration, component definition, IMPLICIT, and FUNCTION statements. ^{[e] }A DATA impliedDO parameter may be an expression involving intrinsic operations with constants and DATA impliedDO variables as operands. ^{[f] }If the I/O FMT= specifier is not of type character, it must be a default integer variable. 
Example 1: The expressions I*3, 1+2*J, 5*J/3, 1, and 10 in the following statement, are all expressions allowed in subscripts and impliedDO parameter expressions in an impliedDO list in a DATA statement:
DATA ((A(I*3), I = 1+2*J, 5*J/3), J = 1, 10) /.../ 
Example 2: An expression such as RADIX(I) is not allowed as a data impliedDO parameter or subscript of a DATA statement object.
An expression such as N, where N is a variable in the scoping unit that contains the DATA statement, is not allowed because N is neither a named constant nor an impliedDO variable in a containing impliedDO list.
Such special expressions in DATA statements are restricted forms of initialization expressions in the sense that the primaries must not include references to any intrinsic function. On the other hand, they are extended forms of initialization expressions in the sense that they permit the use of impliedDO variables that have the scope of the impliedDO list.
The interpretation of an expression specifies the value of the expression when it is evaluated. As with the rules for forming an expression, the rules for interpreting an expression are described from the bottom up, from the interpretation of constants, variables, constructors, and functions to the interpretation of each subexpression to the interpretation of the entire expression.
When an expression is interpreted, the value of each constant and variable is determined. After these are determined, the operations for which the variables and constants are interpreted in precedence order, and a value for the operation is determined by the interpretation rules for each operator. This repeats recursively until the entire expression is interpreted and a value is determined.
The interpretation rules for operations are of two sorts: rules for the intrinsic operations (intrinsic operators with operands of the intrinsic types specified by Table 74) and rules for the defined operations (provided by the programmer using function subprograms). Except for integer division, the intrinsic operations are interpreted by the usual mathematical method, subject to representation limitations imposed by a computer (for example, a finite range of integers, or finite precision of real numbers). The defined operations are interpreted by a function program that is specified in an interface block with a generic specifier of the form OPERATOR(defined_operator).
The interpretation rules for an intrinsic or a defined operation are independent of the context in which the expression occurs. That is, the type, type parameters, and interpretation of any expression do not depend on any part of a larger expression in which it occurs.
When the arguments of the intrinsic operators satisfy the requirements of Table 74, the operations are intrinsic and are interpreted in the usual mathematical way as described in Table 77, except for integer division. For example, the binary operator * is interpreted as the mathematical operation multiplication and the unary operator  is interpreted as negation.
Table 77. Interpretation of the intrinsic operations
Use of operator  Interpretation 

x_{1} ** x_{2}  Raise x_{1} to the power x_{2} 
x_{1} / x_{2}  Divide x_{1} by x_{2} 
x_{1} * x_{2}  Multiply x_{1} by x_{2} 
x_{1}  x_{2}  Subtract x_{2} from x_{1} 
 x_{2}  Negate x_{2} 
x_{1} + x_{2}  Add x_{1} and x_{2} 
+ x_{2}  Same as x_{2} 
x_{1} // x_{2}  Concatenate x_{1} with x_{2} 
x_{1} .LT. x_{2}  x_{1} less than x_{2} 
x_{1} < x_{2}  x_{1} less than x_{2} 
x_{1} .LE. x_{2}  x_{1} less than or equal to x_{2} 
x_{1} <= x_{2}  x_{1} less than or equal to x_{2} 
x_{1} .GT. x_{2}  x_{1} greater than x_{2} 
x_{1} > x_{2}  x_{1} greater than x_{2} 
x_{1} .GE. x_{2}  x_{1} greater than or equal to x_{2} 
x_{1} >= x_{2}  x_{1} greater than or equal to x_{2} 
x_{1} .EQ. x_{2}  x_{1} equal to x_{2} 
x_{1} == x_{2}  x_{1} equal to x_{2} 
x_{1} .NE. x_{2}  x_{1} not equal to x_{2} 
x_{1} /= x_{2}  x_{1} not equal to x_{2} 
x_{1} .LG. x_{2}  x_{1} less than or greater than x_{2} 
x_{1} <> x_{2}  x_{1} less than or greater than x_{2} 
.NOT. x2  True if x_{2} is false 
x_{1} .AND. x_{2}  True if x_{1} and x_{2} are both true 
x_{1} .OR. x_{2}  True if x_{1} and/or x_{2} is true 
x_{1} .NEQV. x_{2}  True if either x_{1} or x_{2} is true, but not both 
x_{1} .XOR. x_{2}  1 if corresponding bits differ; 0 otherwise (bitwise exclusive .OR.) 
x_{1} .EQV. x_{2}  True if both x_{1} or x_{2} are true or both are false 
Except for exponentiation to an integer power, when an operand for a numeric intrinsic operation does not have the same type or type parameters as the result of the operation, the operand is converted to the type, type parameter, and shape of the result and the operation is then performed. For exponentiation to an integer power, the operation can be performed without the conversion of the integer power, say, by developing binary powers of the first operand and multiplying them together to obtain an efficient computation of the result.
For integer division, when both operands are of type integer, the result is of type integer, but the mathematical quotient is often not an integer. In this case, the result is specified to be the integer value closest to the quotient and between zero and the quotient inclusively.
For exponentiation, there are three cases that need to be further described. When both operands are of type integer, the result is of type integer; when x_{2} is negative, the operation x_{1} ** x_{2} is interpreted as the quotient 1/(x_{1}**ABS(x_{2})). Note that it is subject to the rules for integer division. For example, 4**(2) is 0.
The second case occurs when the first operand is a negative value of type integer or real and the second operand is of type real. A program is invalid if it causes a reference to the exponentiation operator with such operands. For example, a program that contains the expression (1.0)**0.5 is an invalid program.
The third case occurs when the second operand is of type real or of type complex. In this case, the result returned is the principal value of the mathematical power function.
There is only one intrinsic character operation: concatenation. For this operation, the operands must be of type character. The length parameter values can be different. The result is of type character with a character length parameter value equal to the sum of the lengths of the operands. The result consists of the characters of the first operand in order followed by those of the second operand in order. For example, 'Fortran' // '95' yields the result 'Fortran 95'.
The intrinsic relational operations perform comparison operations for character and most numeric operands. For these operations, the operands must both be of numeric type or both be of character type. The kind type parameter values of the operands of the numeric types can be different and the lengths of character operands can be different. Complex operands must only be compared for equality and inequality; the reason is that complex numbers are not totally ordered. The result in all cases is of type default logical.
When the operands of an intrinsic relational operation are both numeric, but of different types or type parameters, each operand is converted to the type and type parameters they would have if the two operands were being added. Then, the operands are compared according to the usual mathematical interpretation of the particular relational operator.
When the operands are both of type character, the shorter one is padded on the right with blank padding characters until the operands are of equal length. Then, the operands are compared one character at a time in order, starting from the leftmost character of each operand until the corresponding characters differ. The first operand is less than or greater than the second operand according to whether the characters in the first position where they differ are less than or greater than each other. The operands are equal if both are of zero length or all corresponding characters are equal, including the padding characters.
There is no ordering defined for logical values. However, logical values can be compared for equality and inequality by using the logical equivalence and not equivalence operators .EQV. and .NEQV.. That is, L1 .EQV. L2 is true when L1 and L2 are both true or both false and is false otherwise. L1.NEQV. L2 is true if either L1 or L2 is true (but not both true) and is false otherwise.
The intrinsic logical operations perform many of the common operations for logical computation. For these operations, the operands must both be of logical type but can have different kind type parameters. If the kind type parameter values are the same, the kind type parameter value of the result is the kind type parameter value of the operands. If the kind type parameter values are different, the kind type parameter value is the larger of the two kind type parameter values. The values of the result in all cases are specified in Table 78.
Table 78. The values of operations involving logical operators
x_{1}  x_{2}  .NOT.x_{1}  x_{1}.AND.x_{2}  x_{1}.OR.x_{2}  x_{1}.EQV.x_{2}  x_{1}.NEQV.x_{2} 

True  True  False  True  True  True  False 
True  False  False  False  True  False  True 
False  True  True  False  True  False  True 
False  False  True  False  False  True  False 
Each of the intrinsic operations can have array operands; however, for the binary intrinsic operations, the operands must both be of the same shape, if both are arrays. When one operand is an array and the other is a scalar, the operation behaves as if the scalar operand were broadcast to an array of the result shape and the operation performed.
For both the unary and binary intrinsic operators, the operation is interpreted elementbyelement; that is, the scalar operation is performed on each element of the operand or operands. For example, if A and B are arrays of the same shape, the expression A * B is interpreted by taking each element of A and the corresponding element of B and multiplying them together using the scalar intrinsic operation * to determine the corresponding element of the result. Note that this is not the same as matrix multiplication. As a second example, the expression A is interpreted by taking each element of A and negating it to determine the corresponding element of the result.
For intrinsic operations that appear in masked assignment statements (in WHERE blocks, ELSEWHERE blocks, or in a WHERE statement), the scalar operation is performed only for those elements selected by the logical mask expression.
Note that there is no order specified for the interpretation of the scalar operations. A processor is allowed to perform them in any order, including all at the same time.
The intrinsic operations can have operands with the POINTER attribute. In such cases, each pointer must be associated with a target that is defined, and the value of the target is used as the operand. The target can be scalar or arrayvalued; the rules for interpretation of the operation are those appropriate for the operand being a scalar or an array, respectively.
Recall that an operand can be a structure component that is the component of a structure variable that is itself a pointer. In this case, the value used for the operand is the named component of the target structure associated with the structure variable. For example, consider the following declarations and assume that the pointer PTR is associated with T:
TYPE RATIONAL INTEGER :: N, D END TYPE TYPE(RATIONAL), POINTER :: PTR TYPE(RATIONAL), TARGET :: T 
If PTR%N appears as an operand, its value is the component N of the target T, namely T%N.
The interpretation of a defined operation is provided by a function subprogram with an OPERATOR interface (see the MIPSpro Fortran Language Reference Manual, Volume 2). When there is more than one function with the same OPERATOR interface, the function giving the interpretation of the operation is the one whose dummy arguments match the operands in order, types, kind type parameters, and rank. For example, for the operation A .PLUS. B, where A and B are structures of the derived type RATIONAL, the following interface specifies that the function RATIONAL_PLUS provides the interpretation of this operation.
Example:
INTERFACE OPERATOR(.PLUS.) FUNCTION RATIONAL_PLUS(L, R) USE RATIONAL_MODULE TYPE(RATIONAL), INTENT(IN) :: L, R TYPE(RATIONAL) :: RATIONAL_PLUS END FUNCTION RATIONAL_PLUS FUNCTION LOGICAL_PLUS(L, R) LOGICAL, INTENT(IN) :: L, R LOGICAL :: LOGICAL_PLUS END FUNCTION LOGICAL_PLUS END INTERFACE 
A defined operation is declared by using a function with one or two dummy arguments. (Note that the function can be an entry in an external or module function.)
The dummy arguments to the function represent the operands of the operation. If there is only one, the operation is a unary operation; otherwise it is a binary operation. For a binary operation, the first argument is the left operand and the second is the right operand.
There must be an interface block for the function with the generic specifier of the form OPERATOR (defined_operator).
The types and kind type parameters of the operands in the expression must be the same as those of the dummy arguments of the function.
The function is elemental or the rank of the operands in the expression must match the ranks of the corresponding dummy arguments of the function.
One of the following conditions must be true:
One of the dummy arguments must be of a derived type
Both of the dummy arguments are of intrinsic type but do not match the types and kind type parameters for intrinsic operations as specified in Table 74.
As with the intrinsic operations, the type, type parameters, and interpretation of a defined operation are independent of the context of the larger expression in which the defined operation appears. The interpretation of the same defined operation in different contexts is the same, but the results can be different because the results of the procedure being invoked may depend on values that are not operands and that are different for each invocation.
The relational operators ==, /=, >, >=, <, <, and <> are synonyms for the operators .EQ., .NE., .GT., .GE., .LT., .LE., and .LG.even when they are defined operators. It is invalid, therefore, to have an interface block for both == and .EQ., for example, for which the order, types, type parameters, and rank of the dummy arguments of two functions are the same.
Note: The Fortran standard does not describe the <> or .LG. operators. 
Defined operations are either unary or binary. An existing unary operator (that is, one that has the same name as an intrinsic operator) cannot be defined as a binary operator unless it is also a binary operator. Similarly, an existing binary operator cannot be defined as a unary operator unless it is also a unary operator. However, a defined operator, .PLUS. say, (that is, one that does not have a name that is the same as an intrinsic operator) can be defined as both a unary and binary operator.
The form of the expression and the meaning of the operations establish the interpretation; once established, a compiler can evaluate the expression in any way that provides the same interpretation with one exception; parentheses specify an order of evaluation that cannot be modified. This applies to both intrinsic operations and defined operations.
Essentially, two sorts of alternative evaluations are allowed:
The rearrangement of an expression that yields an equivalent expression; for example, A + B + C can be evaluated equivalently as A + (B + C) and would improve the efficiency of the compiled program if B + C were a subexpression whose value had already been computed.
The partial evaluation of an expression because the value of the unevaluated part can be proven not to affect the value of the entire expression. For example, when one operand of a disjunction (.OR. operator) is known to be true, the other operand need not be evaluated to determine the result of the operation. To be specific, the operand A * B < C need not be evaluated in the expression A < B .OR. A * B < C if A < B is true. This freedom for a compiler to use alternative equivalent evaluations permits the compiler to produce code that is more optimal in some sense (for example, fewer operations, array operations rather than scalar operations, or a reduction in the use of registers or work space), and thereby produce more efficient executable code.
Before describing in more detail the possible evaluation orders, four basic issues need to be addressed, namely, definition of operands, welldefined operations, functions (and defined operations) with side effects, and equivalent interpretations.
Definition status is described in detail in the MIPSpro Fortran Language Reference Manual, Volume 2. For the purpose of evaluation of expressions, it is required that each operand is defined, including all of its parts, if the operand is an aggregate (an array, a structure, or a string). If the operand is a subobject (part of an array, structure, or string), only the selected part is required to be defined. If the operand is a pointer, it must be associated with a target that is defined. An integer operand must be defined with an integer value rather than a statement label.
For the numeric intrinsic operations, the operands must have values for which the operation is welldefined. For example, the divisor for the division operation must be nonzero, and the result of any of the numeric operations must be within the exponent range for the result data type; otherwise, the program is not standard conforming. Other cases include limitations on the operands of the exponentiation operation **: for example, a zerovalued first operand must not be raised to a nonpositive second operand; and a negativevalued first operand of type real cannot be raised to a real power.
The third issue is functions with side effects. In Fortran, functions are allowed to have side effects; that is, they are allowed to modify the state of the program so that the state is different after the function is invoked than before it is invoked. This possibility potentially affects the equivalence of two schemes for evaluating an expression, particularly if the function modifies objects appearing in other parts of the expression. However, Fortran prohibits the formation of statements with these kinds of side effects. That is, a function (or defined operation) within a statement is not permitted to change any entity in the same statement. Exceptions are those statements that have statements within them, for example, an IF statement or a WHERE statement. In these cases, the evaluation of functions in the logical expressions in parentheses after the IF keyword or WHERE keyword are allowed to affect objects in the statement following the closing right parenthesis. For example, if F and G are functions that change their actual argument I, the following statements are valid, even though I is changed when the functions are evaluated:
IF (F(I)) A = I WHERE (G(I)) B = I 
The following statements are examples of statements that are not valid because F and G change I, which is used elsewhere in the same statement:
A(I) = F(I) Y = G(I) + I 
It is also not valid for there to be two function references in a statement, if each causes a side effect and the order in which the functions are invoked yields a different final status, even though nothing in the statement is changed.
The fourth issue is equivalent interpretation. For the numeric intrinsic operations, the definition of equivalent interpretation is defined as being mathematical equivalence of the expression, not computational equivalence. Mathematical equivalence assumes exact arithmetic (no rounding errors and infinite exponent range) and thus assumes the rules of commutativity, associativity, and distributivity as well as other rules that can be used to determine equivalence (except that the order of operations specified by parentheses must be honored). Under these assumptions, two evaluations are mathematically equivalent if they yield the same values for all possible values of the operands. A + B + C and A + (B + C) are thus mathematically equivalent but are not necessarily computationally equivalent because of possible different rounding errors. On the other hand, I/2 and 0.5 * I (where I is an integer) is a mathematical difference because of the special Fortran definition of integer division.
Table 79, gives examples of equivalent evaluations of expressions where A, B, and C are operands of type real or complex, and X, Y, and Z are of any numeric type. All of the variables are assumed to be defined and have values that make all of the operations in this table welldefined.
Table 79. Equivalent evaluations for numeric intrinsic operations
Expression  Equivalent evaluations 

X+Y  Y+X 
X*Y  Y*X 
X+Y  YX 
X+Y+Z  X+(Y+Z) 
XY+Z  X(YZ) 
X*A/Z  X*(A/Z) 
X*YX*Z  X*(YZ) 
A/B/C  A/(B*C) 
A/5.0  0.2*A 
Table 710 provides examples of alternative evaluations that are not valid and are not mathematically equivalent to the original expression. In addition to the operands of the same names used in Table 79, Table 710 uses I and J as operands of type integer. Recall that when both operands of the division operator are of type integer, a Fortran integer division truncates the result toward zero to obtain the nearest integer quotient.
Table 710. Nonequivalent evaluations of numeric expressions
Expression  Prohibited evaluations 

I/2  0.5*I 
X*I/J  X*(I/J) 
I/J/A  I/(J*A) 
(X+Y)+Z  X+(Y+Z) 
(X*Y)(X*Z)  X*(YZ) 
X*(YZ)  X*YX*Z 
For character, relational, and logical intrinsic operations, the definition of the equivalence of two evaluations is that, given the same values for their operands, each evaluation produces the same result. The definition for equivalence of two evaluations of the same defined operation also requires the results to be the same; note that this definition is more restrictive than for the numeric intrinsic operations, because only mathematical equivalence need be preserved for numeric operations. As described for numeric intrinsic operations, a compiler can choose any evaluation scheme equivalent to that provided by the interpretation. Table 711 gives some equivalent schemes for evaluating a few example expressions. For these examples, I and J are of type integer; L1, L2, and L3 are of type logical; and C1, C2, and C3 are of type character of the same length. All of the variables are assumed to be defined.
Table 711. Equivalent evaluations of other expressions
Expression  Equivalent evaluations 

I .GT. J  (IJ) .GT. 0 
L1 .OR. L2 .OR. L3  L1 .OR. (L2 .OR. L3) 
L1 .AND. L1  L1 
C3 = C1//C2  C3=C1 (C1, C2, C3 all of the same length) 
These rules for equivalent evaluation schemes allow the compiler to not evaluate any part of an expression that has no effect on the resulting value of the expression. Consider the expression X*F(Y), where F is a function and X has the value 0. The result will be the same regardless of the value of F(Y); therefore, F(Y) need not be evaluated. This shortened evaluation is allowed in all cases, even if F(Y) has side effects. In this case every data object that F could affect is considered to be undefined after the expression is evaluated (that is, it does not have a predictable value).
The appearance of an array element, an array section, or a character substring reference requires, in most cases, the evaluation of the expressions that are the subscripts, strides, or substring ranges. The type or type parameters of the containing expression are not affected by the evaluation of such subscript, stride, or substring range expressions. It is not necessary for these expressions to be evaluated, if the array section can be shown to be zerosized or the substring can be shown to be of a zerolength by other means. For example, in the expression A(1:0) + B( expr_{1}: expr_{2}), expr_{1} and expr_{ 2} need not be evaluated because the conformance rules for intrinsic operations require that the section of B be zerosized.
The type and type parameters, if any, of a constructor are not affected by the evaluation of any expressions within the constructor.
Parentheses within the expression must be honored. This is particularly important for computations involving numeric values in which rounding errors or range errors may occur or for computations involving functions with side effects.
The most common use of the result of an expression is to give a value to a variable. This is done with an assignment statement. For example:
RUG = BROWN + 2.34 / TINT 
The forms of intrinsic assignment, defined assignment, and masked array assignment are the same, and they are defined as follows:
 assignment_stmt  is 

Assignment establishes a value for the variable on the left of the assignment symbol in an assignment statement. Execution of the assignment statement causes the expression to be evaluated (by performing the computation indicated), and then the value of the expression is assigned to the variable. If the variable has subscripts, section subscripts, or a substring range, the execution of the assignment statement must behave as if they were evaluated before any part of the value is assigned.
There are four forms of the assignment statement: intrinsic assignment, defined assignment, pointer assignment, and masked array assignment.
An assignment statement is a defined assignment if the following conditions are true:
There is a subroutine subprogram with an assignment interface of the form ASSIGNMENT (=).
The types, kind type parameters, and ranks (if arrays) of the variable and expression match in order the dummy arguments of the subroutine with the assignment interface.
An assignment statement is a masked array assignment if it appears in a WHERE construct, WHERE statement, FORALL statement, or FORALL construct; otherwise, it is an intrinsic or defined assignment.
The form of the pointer assignment statement is similar to the assignment statement except that the assignment operator is => instead of =.
The rules and restrictions for each of these forms of assignment are different and are described in the sections below for each form of assignment.
The following examples show the forms of assignment:
Expression  Meaning  
X = X + 1.0  Intrinsic assignment for reals  
CHAR(1:4) = "A123"  Intrinsic assignment for characters  
STUDENT = B_JONES  Intrinsic assignment for structures if STUDENT and B_JONES are of the same derived type  
STRING = "Brown"  Defined assignment for structure if STRING is of derived type and an interface exists that defines the operator = for the types STRING and character  
X=Y  Defined elemental assignment in which X and Y are both arrays of derived type. In addition, an interface exists that defines the operator = for the type and shape of the array, and the specific is elemental.  
WHERE (Z /= 0.0) A = B / Z END WHERE  Masked array assignment  
PTR => X  Pointer assignment 
Intrinsic assignment can be used to assign a value to a nonpointer variable of any type or to the target associated with a pointer variable. The assignment statement defines or redefines the value of the variable or the target, as appropriate. The value is determined by the evaluation of the expression on the right side of the equal sign.
The types and kind parameters of the variable and expression in an intrinsic assignment statement must be of the types given in Table 712.
Table 712. Types of the variable and expression in an intrinsic assignment
Type of the variable  Type of the expression 

Integer  Integer, real, complex, Boolean, Cray pointer 
Real  Integer, real, complex, Boolean 
Complex  Integer, real, complex 
Character  Character 
Logical  Logical 
Cray pointer  Cray pointer, integer, Boolean 
Derived type  Same derived type as the variable 
Note: The Fortran standard does not define Boolean or Cray pointer types. 
If the variable is an array, the expression must either be a scalar or an array of the same shape as the variable. If the variable is a scalar, the expression must be a scalar. The shape of the variable can be specified in specification statements if it is an explicitshape array. The shape of the variable can be determined by the section subscripts in the variable, by an actual argument if it is a assumedshape array, or by an ALLOCATE statement or a pointer assignment statement if it is a deferredshape array. It must not be an assumedsize array unless there is a vector subscript, a scalar subscript, or a section subscript containing an upper bound in the last dimension of the array. The shape of the expression is determined by the shape of the operands, the operators in the expression, and the functions referenced in the expression. A complete description of the shape of an expression appears in Section 7.2.8.3.
If the variable is a pointer, it must be associated with a target; the assignment statement assigns the value of the expression to the target of the pointer. The pointer can be associated with a target that is an array; the pointer determines the rank of the array, but the extents in each dimension are that of the target.
The evaluation of the expression on the righthand side of the equal sign, including subscript and section subscript expressions that are part of the expression and part of the variable, must be performed before any portion of the assignment is performed. Before the assignment begins, any necessary type conversions are completed if the variable has a different numeric type or type parameter from the expression. The conversion is the same as that performed by the conversion intrinsic functions INT(3i), REAL(3i), CMPLX(3i), and LOGICAL(3i), as specified in Table 713. The result of a Boolean expression is of type integer; no conversion is done for BOZ or Hollerith constants.
Note: The Fortran standard does not specify type Boolean or BOZ constants in assignment statements. 
Table 713. Conversion performed on an expression before assignment
Type of the variable  Value assigned 

Integer  INT (expr, KIND (variable)) 
Real  REAL (expr, KIND (variable)) 
Complex  CMPLX (expr, KIND (variable)) 
Logical  LOGICAL (expr, KIND (variable)) 
An expression can use parts of the variable that appear on the left side of an assignment statement. For example, in evaluating a character string expression on the righthand side of an assignment, the values in the variable on the lefthand side can be used, as in the following example:
DATE(2:5) = DATE(1:4) 
If the variable and expression are of character type with different lengths, the assignment occurs as follows:
If the length of the variable is less than that of the expression, the value of the expression is truncated from the right.
If the length of the variable is greater than the expression, the value of the expression is filled with blanks on the right.
The evaluation of expressions in the variable on the lefthand side, such as subscript expressions, has no effect on, nor is affected by, the evaluation of the expression on the righthand side, which is evaluated completely first. As usual, this requirement that the expression on the right be evaluated first is specifying the semantics of the statement and does not imply that an implementation must perform the computation in this way if there is an equivalent order that computes the same result.
When a scalar is assigned to an array, the assignment behaves as if the scalar is broadcast to an array of the shape of the variable; it is then in shape conformance with the variable. In the following example, all ten elements of the array A are assigned the value 1.0:
REAL A(10) A = 1.0 
Array assignment is elementbyelement, but the order is not specified. Assume that A and B are real arrays of size 10, and the whole array assignment is as follows:
A = B 
The first element of B would be assigned to the first element of A, the second element of B would be assigned to the second element of A, and this would continue elementbyelement for 10 elements. The assignment of elements, however, may be performed in any order.
For derivedtype intrinsic assignment, the derived types of the variable and the expression must be the same. Derivedtype intrinsic assignment is performed componentbycomponent following the above rules, except when a component is a pointer. For pointer components, pointer assignment between corresponding components is used.
A defined assignment is an assignment operation provided by a subroutine with an assignment interface ASSIGNMENT (=). When the variable and expression in the assignment statement are of intrinsic types and do not satisfy the type matching rules described in Table 712, or are of derived type, a defined assignment operation will be used, provided the assignment interface and subroutine are accessible. For example, a defined assignment may apply when an integer object is to be assigned to a logical variable, provided a subroutine with a generic assignment interface is accessible. Assignment thus can be extended to types other than the intrinsic types or can replace the intrinsic assignment operation for derived types, if the programmer defines the rules for this assignment in a subroutine. For more information on the assignment interface, see the MIPSpro Fortran Language Reference Manual, Volume 2.
An assignment operation is declared by using a subroutine with two dummy arguments.
The dummy arguments to the subroutine represent the variable and the expression, in that order.
There must be an interface block for the subroutine with the generic specifier of the form ASSIGNMENT(=).
The types and kind type parameters of the variable and expression in the assignment statement must be the same as those of the dummy arguments.
The rank of the variable and the expression in the assignment must match the ranks of the corresponding dummy arguments.
One of the following conditions must be true:
One of the dummy arguments must be of a derived type
Both of the dummy arguments are of intrinsic type but do not match the types and kind type parameters for intrinsic operations as specified in Table 712.
The subroutine is elemental, and either both dummy arguments have the same shape or one is scalar.
Example:
INTERFACE ASSIGNMENT (=) SUBROUTINE RATIONAL_TO_REAL(L, R) USE RATIONAL_MODULE TYPE(RATIONAL), INTENT(IN) :: R REAL, INTENT(OUT) :: L END SUBROUTINE RATIONAL_TO_REAL SUBROUTINE REAL_TO_RATIONAL(L, R) USE RATIONAL_MODULE REAL, INTENT(IN) :: R TYPE(RATIONAL), INTENT(OUT) :: L END SUBROUTINE REAL_TO_RATIONAL END INTERFACE 
The preceding interface block specifies two defined assignments for two assignment operations in terms of two external subroutines, one for assignment of objects of type RATIONAL to objects of type real, and the other for assignment of objects of type real to objects of type RATIONAL. With this interface block, the following assignment statements are defined:
REAL R_VALUE TYPE(RATIONAL) RAT_VALUE R_VALUE = RATIONAL(1, 2) RAT_VALUE = 3.7 
The effect of the defined assignment on variables in the program is determined by the referenced subroutine.
A pointer is a variable with the POINTER attribute that points to another object. The term pointer association is used for the concept of "pointing to" and the term target is used for the object associated with a pointer.
A pointer assignment associates a pointer with a target. If the target is disassociated or undefined, the pointer becomes disassociated or undefined according to the status of the target.
Once a pointer assignment has been executed, the association status of the pointer remains unchanged until one of the following events occurs:
Another pointer assignment statement is executed that redefines the pointer.
An ALLOCATE, DEALLOCATE, or NULLIFY statement is executed that redefines the pointer.
A RETURN statement is executed. This changes the association status only if the pointer is local to the subprogram containing the return and the pointer does not have the SAVE attribute.
The pointer assignment statement is defined as follows:
 pointer_assignment_stmt  is  pointer_object => target 
 pointer_object  is  variable_name 

 or  structure_component 
 target  is  variable 

 or  expr 
If the pointer object is a variable name, the name must have the POINTER attribute. If the pointer object is a structure component, the component must have the POINTER attribute.
The form of the expression permitted as a target is severely limited.
If the target is a variable, then it must have one of the following characteristics:
It must have the TARGET attribute.
It must be the component of a structure, the element of an array variable, or the substring of a character variable that has the TARGET attribute.
It must have the POINTER attribute.
The type, kind type parameters (including length, if character), and rank of the target must be the same as the pointer object.
If the variable on the right of => has the TARGET attribute, the pointer object on the left of => becomes associated with this target.
If the variable on the right of => has the POINTER attribute and is associated, the pointer object on the left of => points to the same target data that the right hand pointer points to after the pointer assignment statement is executed.
If the variable on the right of => has the POINTER attribute and is disassociated, or if it is a reference to the NULL(3i) intrinsic, the pointer object on the left of => becomes disassociated.
If the variable on the right of => has the POINTER attribute and has an undefined association status, the association status of the pointer object on the left of => becomes undefined.
A pointer assignment statement terminates any previous association for that pointer and creates a new association.
If the pointer object is a deferredshape array, the pointer assignment statement establishes the extents for each dimension of the array, unless the target is a disassociated or undefined pointer. Except for the case of a disassociated or undefined pointer, the extents are those of the target. For example, if the following statements have been processed, the extents of P1 are those of T, namely 11 and 20, but those of P2 are 1 and 10, because T(:) has a section subscript list:
INTEGER, TARGET :: T(11:20) INTEGER, POINTER :: P1(:), P2(:) P1 => T P2 => T(:) 
The target must not be a variable that is an assumedsize array. If it is an array section of an assumedsize array, the upper bound for the last dimension must be specified.
If the target is an array section, it must not have a vector subscript.
If the target is an expression, it must deliver a pointer result. This implies that the expression must be a userdefined function reference or defined operation that returns a pointer (there are no intrinsic operations or functions that return results with the POINTER attribute). This also implies that a pointer can never point at a constant because constants cannot have the TARGET attribute.
If the target of a pointer cannot be referenced or defined, the pointer must not be referenced or defined.
If a structure has a component with the POINTER attribute and the structure is assigned a value using an intrinsic derivedtype assignment, pointer assignment is used for each component with the POINTER attribute. Also, defined assignment may cause pointer assignment between some components of a structure.
Note that when a pointer appears on the right side of => in a pointer assignment, the pointer on the left side of => is defined or redefined to be associated with the target on the right side of the =>; neither the pointer on the right nor its target are changed in any way.
General examples:
MONTH => DAYS(1:30) PTR => X(:, 5) NUMBER => JONES % SOCSEC 
Example 1: In this example, the target is another pointer:
REAL, POINTER :: PTR, P REAL, TARGET :: A REAL B A = 1.0 P => A PTR => P B = PTR + 2.0 
The previous program segment defines A with the value 1.0, associates P with A; then PTR is associated with A as well (through P). The value assigned to B in the regular assignment statement is 3.0, because the reference to PTR in the expression yields the value of the target A which is the value 1.0.
Example 2: In this example, the target is an expression:
INTERFACE FUNCTION POINTER_FCN(X) REAL X REAL, POINTER :: POINTER_FCN END FUNCTION END INTERFACE REAL, POINTER :: P REAL A P => POINTER_FCN(A) 
In this example, the function POINTER_FCN takes a real argument and returns a pointer to a real target. After execution of the pointer assignment statement, the pointer P points to this real target.
Pointers can become associated by using the ALLOCATE statement instead of a pointer assignment statement. Pointers can become disassociated by using the DEALLOCATE or NULLIFY statements, as well as with the pointer assignment statement.
A pointer can be used in an expression (see Section 7.3.1.4, for the details). Briefly, any reference to a pointer in an expression, other than in a pointer assignment statement, or in certain procedure references, yields the value of the target associated with the pointer. When a pointer appears as an actual argument corresponding to a dummy argument that has the POINTER attribute, the reference is to the pointer and not the value. Note that a procedure must have an explicit interface if it has a dummy argument with the POINTER attribute. For information on explicit interfaces, see the MIPSpro Fortran Language Reference Manual, Volume 2.
Sometimes it is desirable to assign only certain elements of one array to another array. To invert the elements of an array elementbyelement, for example, you have to avoid elements that are 0. The masked array assignment is ideal for such selective assignment, as the following example using a WHERE construct illustrates:
REAL A(10,10) ... WHERE (A /= 0.0) RECIP_A = 1.0 / A ! Assign only where the ! elements are nonzero ELSEWHERE RECIP_A = 1.0 ! Use the value 1.0 for ! the zero elements END WHERE 
The first array assignment statement is executed for only those elements where the mask A /= 0.0 is true. Next, the second assignment statement (after the ELSEWHERE statement) is executed for only those elements where the same mask is false. If the values of RECIP_A where A is 0 are never used, this example can be simply written by using the WHERE statement, rather than the WHERE construct, as follows:
WHERE (A /= 0.0) RECIP_A = 1.0 / A 
A masked array assignment is an intrinsic assignment statement in a WHERE block, an ELSEWHERE block, or a WHERE statement for which the variable being assigned is an array. The WHERE statement and WHERE construct appear to have the characteristics of a control statement or construct such as the IF statement and IF construct. But there is a major difference: every assignment statement in a WHERE construct is executed, whereas at most one block in the IF construct is executed. Similarly, the assignment statement following a WHERE statement is always executed. For this reason, WHERE statements and constructs are discussed here under assignment rather than under control constructs.
In a masked array assignment, the assignment is made to certain elements of an array based on the value of a logical array expression serving as a mask for picking out the array elements. The logical array expression acts as an arrayvalued condition on the elemental intrinsic operations, functions, and assignment for each array assignment statement in the WHERE statement or WHERE construct.
As in an intrinsic array assignment, a pointer to an array can be used as the variable, and a pointer to a scalar or an array can be used as a primary in the expression. If the target of the pointer is an array, the target array is masked in the same manner as a nonpointer array used in a masked array assignment.
The WHERE construct is defined as follows:
 where_stmt  is 
 
 where_construct  is 
 
 where_construct_stmt  is 
 
 where_body_construct  is 
 

 or 
 

 or 
 
 where_assignment_stmt  is 
 
 mask_expr  is 
 
 masked_elsewhere_stmt  is 
 
 elsewhere_stmt  is 
 
 end_where_stmt  is 

The definition of the WHERE construct can be simplified to the following general format:
WHERE (condition_1) ! STATEMENT_1 ... ELSEWHERE (condition_2) ! STATEMENT_2 ... ELSEWHERE ! STATEMENT_3 ... END WHERE 
The following information applies to the preceding general format:
Following execution of STATEMENT_1, the control mask has the value condition_1 and the pending control mask has the value .NOT.condition_1.
Following execution of STATEMENT_2, the control mask has the value (.NOT.condition_1).AND.condition_2 and the pending control mask has the value (.NOT.condition_1).AND.(.NOT.condition_2).
Following execution of STATEMENT_3, the control mask has the value (.NOT.condition_1).AND.(.NOT.condition_2).
The false condition values are propogated through the execution of the masked ELSEWHERE statement.
If an array constructor appears in a where_assignment_stmt or in a mask_expr, the array constructor is evaluated without any masked control. After that, the where_assignment_stmt is executed or the mask_expr is evaluated.
When a where_assignment_stmt is executed, the values of expr that correspond to true values of the control mask are assigned to the corresponding elements of variable.
A statement that is part of a where_body_construct must not be a branch target statement. The value of the control mask is established by the execution of a WHERE statement, a WHERE construct statement, an ELSEWHERE statement, a masked ELSEWHERE statement, or an ENDWHERE statement. Subsequent changes to the value of entities in a mask_expr have no effect on the value of the control mask. The execution of a function reference in the mask expression of a WHERE statement is permitted to affect entities in the assignment statement. Execution of an END WHERE has no effect.
If the where_construct_stmt has a where_construct_name, then the corresponding end_where_stmt must specify the same name. If the construct also has an elsewhere_stmt or masked_ elsewhere_stmt, it must have the same where_construct_name. If no where_construct_name is specified for the where_construct, then the end_where_stmt and any elsewhere_stmt or masked_elsewhere_stmt must have the where_construct_name.
In a WHERE construct, only the WHERE construct statement can be labeled as a branch target statement.
The WHERE block is the set of assignments between the WHERE construct statement and the ELSEWHERE statement (or END WHERE statement, if the ELSEWHERE statement is not present). The ELSEWHERE block is the set of assignment statements between the ELSEWHERE and the END WHERE statements.
Each assignment in the ELSEWHERE block assigns a value to each array element that corresponds with a mask array element that is false.
The ELSEWHERE block is optional; when it is not present, no assignment is made to elements corresponding to mask array elements that are false.
All of the assignment statements are executed in sequence as they appear in the construct (in both the WHERE and ELSEWHERE blocks).
Any elemental intrinsic operation or function within an array assignment statement is evaluated only for the selected elements. In the following example, the square roots are taken only of the elements of A that are positive:
REAL A(10, 20) ... WHERE (A > 0.0) SQRT_A = SQRT(A) END WHERE 
An elemental function reference is evaluated independently for each element, and only those elements needed in the array assignment are referenced. A where_assignment_stmt that is a defined assignment must be elemental.
The expression in the array assignment statement can contain nonelemental function references. Nonelemental function references are references to any function or operation defined by a subprogram, without the ELEMENTAL keyword. All elements of the arguments of such functions and returned results (if arrays) are evaluated in full. If the result of the nonelemental function is an array and is an operand of an elemental operation or function, then only the selected elements are used in evaluating the remainder of the expression.
Example 1:
REAL A(2, 3), B(3, 10), C(2, 10), D(2, 10) INTRINSIC MATMUL ... WHERE (D < 0.0) C = MATMUL(A, B) END WHERE 
The matrix product A multiplied by B is performed, yielding all elements of the product, and only for those elements of D that are negative are the assignments to the corresponding elements of C made.
Example 2:
WHERE (TEMPERATURES > 90.0) HOT_TEMPS = TEMPERATURES WHERE (TEMPERATURES < 32.0) COLD_TEMPS = TEMPERATURES 
Example 3:
WHERE (TEMPERATURES > 90.0) NUMBER_OF_SWEATERS = 0 ELSEWHERE (TEMPERATURES < 0.0) NUMBER_OF_SWEATERS = 3 ELSEWHERE (TEMPERATURES < 40) NUMBER_OF_SWEATERS = 2 ELSEWHERE NUMBER_OF_SWEATERS = 1 ENDWHERE 
One major difference between the WHERE construct and control constructs has been described in Section 7.5.4. Another difference is that no transfers out of WHERE or ELSEWHERE blocks are possible (except by a function reference) because only intrinsic assignment statements are permitted within these blocks. Note that the execution of statements in the WHERE block can affect variables referenced in the ELSEWHERE block (because the statements in both blocks are executed).
FORALL statements and constructs control the execution of assignment and pointer assignment statements with selection by using index values and an optional mask expression.
The FORALL construct allows multiple assignments, masked array (WHERE) assignments, and nested FORALL constructs and statements to be controlled by a single forall_triplet_spec_list and scalar_mask.
The format of the FORALL construct is as follows:
 forall_construct  is 
 
 forall_construct_stmt  is 
 
 forall_header  is 
 
 forall_triplet_spec  is 
 
 subscript  is 
 
 stride  is 
 
 forall_body_construct  is 
 

 or 
 

 or 
 

 or 
 

 or 
 
 forall_assignment_stmt  is 
 

 or 
 
 end_forall_stmt  is 

If the forall_construct_stmt has a forall_construct_name, the end_forall_stmt must have the same forall_construct_name. If the end_forall_stmt has a forall_construct_name, the forall_construct_stmt must have the same forall_construct_name.
The scalar_mask_expr must be scalar and of type logical.
A procedure that is referenced in the scalar_mask_expr, including one referenced by a defined operation, must be a pure procedure.
A procedure that is referenced in a forall_body_construct, including one referenced by a defined operation or assignment, must be a pure procedure.
The index_name must be a named scalar variable of type integer.
A subscript or stride in a forall_triplet_spec must not contain a reference to any index_name in the forall_triplet_spec_list in which it appears.
A statement in a forall_body_construct must not define an index_name of the forall_construct.
A forall_body_construct must not be a branch target.
Example:
REAL :: A(10, 10), B(10, 10) = 1.0 ... FORALL (I = 1:10, J = 1:10, B(I, J) /= 0.0) A(I, J) = REAL (I + J  2) B(I, J) = A(I, J) + B(I, J) * REAL (I * J) END FORALL 
Each forall_body_construct is executed in the order in which it appears. Each construct is executed for all active combinations of the index_name values.
Execution of a forall_assignment_stmt that is an assignment_stmt causes the evaluation of expr and all expressions within variable for all active combinations of index_name values. After all evaluations have been performed, each expr value is assigned to the corresponding variable.
Execution of a forall_assignment_stmt that is a pointer_assignment_stmt causes the evaluation of all expressions within target and pointer_object, the determination of any pointers within pointer_object, and the determination of the target for all active combinations of index_name values. After these evaluations have been performed, each pointer_object is associated with the corresponding target.
In a forall_assignment_stmt, a defined assignment subroutine must not reference any variable that becomes defined or a pointer_object that becomes associated by the statement.
The following code fragment shows a FORALL construct with two assignment statements. The assignment to array B uses the values of array A computed in the previous statement, not the values A had prior to execution of the FORALL:
FORALL (I = 2:N1, J = 2:N1 ) A (I, J) = A(I, J1) + A(I,J+1) + A(I1,J) + A(I+1, J) B (I, J) = 1.0 / A(I, J) END FORALL 
The following code fragment shows how to avoid an error condition by using an appropriate scalar_mask_expr that limits the active combinations of the index_name values:
FORALL (I = 1:N, Y(I) .NE. 0.0) X(I) = 1.0 / Y(I) END FORALL 
Each statement in a where_construct within a forall_construct is executed in sequence. When a where_stmt, where_construct_stmt, or masked_elsewhere_stmt is executed, the statement's mask_expr is evaluated for all active combinations of index_name values as determined by the outer forall_constructs, masked by any control mask corresponding to outer where_constructs. Any where_assignment_stmt is executed for all active combinations of index_name values, masked by the control mask in effect for the where_assignment_stmt. The following FORALL construct contains a WHERE statement and an assignment statement:
INTEGER A(5,4), B(5,4) FORALL ( I = 1:5 ) WHERE ( A(I,:) .EQ. 0 ) A(I,:) = I B (I,:) = I / A(I,:) END FORALL 
The preceding code is executed with array A as follows::
0 0 0 0 1 1 1 0 A = 2 2 0 2 1 0 2 3 0 0 0 0 
The result is as follows:
1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 1 A = 2 2 3 2 B = 1 1 1 1 1 4 2 3 4 1 2 1 5 5 5 5 1 1 1 1 
When a forall_stmt or forall_construct is executed, the compiler evaluates the subscript and stride expressions in the forall_triplet_spec_list for all active combinations of the index_name values of the outer FORALL construct. The set of combinations of index_name values for the inner FORALL is the union of the sets defined by these bounds and strides for each active combination of the outer index_name values; it also includes the outer index_name values. The scalar_mask_expr is then evaluated for all combinations of the index_name values of the inner construct to produce a set of active combinations for the inner construct. If no scalar_mask_expr is specified, the compiler uses .TRUE. as its value. Each statement in the inner FORALL is then executed for each active combination of the index_name values. The following FORALL construct contains a nested FORALL construct. It assigns the transpose of the lower triangle of array A, which is the section below the main diagonal, to the upper triangle of A. The code fragment is as follows:
INTEGER A (3, 3) FORALL (I = 1:N1 ) FORALL ( J=I+1:N ) A(I,J) = A(J,I) END FORALL END FORALL 
Prior to execution of the preceding code, N=3 and array A is as follows:
0 3 6 A = 1 4 7 2 5 8 
After the preceding code is executed, array A is as follows:
0 1 2 A = 1 4 5 2 5 8 
You could also use the following FORALL statement to obtain identical results:
FORALL ( I = 1:N1, J=1:N, J > I ) A(I,J) = A(J,I) 
For more information on the FORALL statement, see Section 7.5.5.2.
The FORALL statement allows a single assignment statement or pointer assignment to be controlled by a set of values and an optional mask expression. The format for this statement is as follows:
Execution of a FORALL statement starts with the evaluation of the forall_triplet_spec_list for each index_name variable. All possible combinations of the values of the index_name variables are considered for execution of the FORALL body. The mask expression, if present, is then evaluated for each combination of index_name values and each combination that has a .TRUE. outcome is in the active combination of index_name values. This set of active combinations is then used in executing the FORALL body.
A FORALL statement is equivalent to a FORALL construct that contains a single forall_body_construct that is a forall_assignment_stmt.
The scope of an index_name in a forall_stmt is the statement itself.
The following FORALL statement assigns the elements of vector X to the elements of the main diagonal of matrix A:
FORALL (I=1:N) A(I,I) = X(I) 
In the following FORALL statement, array element X(I,J) is assigned the value (1.0 / REAL (I+J1)) for values of I and J between 1 and N, inclusive:
FORALL (I = 1:N, J = 1:N) X(I,J) = 1.0 / REAL (I+J1) 
The following statement takes the reciprocal of each nonzero offdiagonal element of array Y(1:N, 1:N) and assigns it to the corresponding element of array X. Elements of Y that are zero or are on the diagonal do not participate, and no assignments are made to the corresponding elements of X:
FORALL (I=1:N, J=1:N, Y(I,J) /= 0 .AND. I /= J) X(I,J) = 1.0 / Y(I,J) 
A manytoone assignment is more than one assignment to the same object or subobject, or association of more than one target with the same pointer, whether the object is referenced directly or indirectly through a pointer. A manytoone assignment must not occur within a single statement in a FORALL construct or statement. It is possible to assign, or pointer assign, to the same object in different assignment statements in a FORALL construct.
The appearance of each index_name in the identification of the lefthand side of an assignment statement is helpful in eliminating manytoone assignments, but it is not sufficient to guarantee that there will be none. The following code fragment is permitted only if INDEX(1:10) contains no repeated values:
FORALL (I = 1:10) A (INDEX (I)) = B(I) END FORALL 
Within the scope of a FORALL construct, a nested FORALL statement or FORALL construct cannot have the same index_name. The forall_header expressions within a nested FORALL can depend on the values of outer index_name variables.