How expressions are evaluated
Precedence of operators
An expression can contain more than one kind of operator. When it does,
the expression is evaluated from left to right, according to the following
precedence among operators:
- Defined unary
- Arithmetic
- Character
- Relational
- Logical
- Defined binary
For example, the logical expression:
L .OR. A + B .GE. C
where L is of type logical, and A, B,
and C are of type real, is evaluated the same as the logical expression
below:
L .OR. ((A + B) .GE. C)
An extended intrinsic operator maintains its precedence. That is, the operator
does not have the precedence of a defined unary operator or a defined binary
operator.
Summary of interpretation rules
Primaries that contain operators are combined in the following order:
- Use of parentheses
- Precedence of the operators
- Right-to-left interpretation of exponentiations in a factor
- Left-to-right interpretation of multiplications and divisions in a term
- Left-to-right interpretation of additions and subtractions in an arithmetic
expression
- Left-to-right interpretation of concatenations in a character expression
- Left-to-right interpretation of conjunctions in a logical term
- Left-to-right interpretation of disjunctions in a logical disjunct
- Left-to-right interpretation of logical equivalences in a logical expression
Evaluation of expressions
Arithmetic, character, relational, and logical expressions are evaluated
according to the following rules:
- A variable or function must be defined at the time it is used. You must
define an integer operand with an integer value, not a statement label value.
All referenced characters in a character data object or referenced array elements
in an array or array section must be defined at the time the reference is
made. All components of a structure must be defined when a structure is referenced.
A pointer must be associated with a defined target.
Execution of an array
element reference, array section reference, and substring reference requires
the evaluation of its subscript, section subscript and substring expressions.
Evaluation of any array element subscript, section subscript, substring expression,
or the bounds and stride of any array constructor implied-DO does
not affect, nor is it affected by, the type of the containing expression.
See Expressions involving arrays. You cannot use any constant integer operation
or floating-point operation whose result is not mathematically defined in
an executable program. If such expressions are nonconstant and are executed,
they are detected at run time. (Examples are dividing by zero and raising
a zero-valued primary to a zero-valued or negative-valued power.) As well,
you cannot raise a negative-valued primary of type real to a real power.
- The invocation of a function in a statement must not affect, or be affected
by, the evaluation of any other entity within the statement in which the function
reference appears. When the value of an expression is true, invocation of
a function reference in the expression of a logical IF statement
or a WHERE statement can affect entities in the statement that is
executed. If a function reference causes definition or undefinition of an
actual argument of the function, that argument or any associated entities
must not appear elsewhere in the same statement. For example, you cannot use
the statements:
A(I) = FUNC1(I)
Y = FUNC2(X) + X
if the reference to FUNC1 defines I or the reference to FUNC2 defines X.
The
data type of an expression in which a function reference appears does not
affect, nor is it affected by, the evaluation of the actual arguments of the
function.
- An argument to a statement function reference must not be altered by evaluating
that reference.
IBM Extension
Several compiler options affect the data type of the final result:
- When you use the -qintlog compiler option, you can mix integer
and logical values in expressions and statements. The data type and kind type
parameter of the result depends on the operands and the operator involved.
In general:
- For unary logical operators (.NOT.) and arithmetic unary operators
(+,-):
Data Type of OPERAND |
Data Type of RESULT of Unary Operation |
BYTE |
INTEGER(1) |
INTEGER(n) |
INTEGER(n) |
LOGICAL(n) |
LOGICAL(n) |
Typeless |
Default integer |
where n represents the kind type parameter. n must
not be replaced with a logical constant even if -qintlog is on, nor
by a character constant even if -qctyplss is on, nor can it be a
typeless constant. In the case of INTEGER and LOGICAL data
types, the length of the result is the same as the kind type parameter of
the operand.
- For binary logical operators (.AND., .OR., .XOR., .EQV., .NEQV.) and arithmetic binary operators (**, *, /, +, -), the following table
summarizes what data type the result has:
|
second operand |
first
operand
|
BYTE |
INTEGER(y) |
LOGICAL(y) |
Typeless |
BYTE |
INTEGER(1) |
INTEGER(y) |
LOGICAL(y) |
INTEGER(1) |
INTEGER(x) |
INTEGER(x) |
INTEGER(z) |
INTEGER(z) |
INTEGER(x) |
LOGICAL(x) |
LOGICAL(x) |
INTEGER(z) |
LOGICAL(z) |
LOGICAL(x) |
Typeless |
INTEGER(1) |
INTEGER(y) |
LOGICAL(y) |
Default integer |
Note:
z is the kind type parameter
of the result such that z is equal to the greater of x and y. For example, a logical expression with a LOGICAL(4) operand
and an INTEGER(2) operand has a result of INTEGER(4).
For binary logical operators (.AND., .OR., .XOR., .EQV., .NEQV.), the result of a logical operation
between an integer operand and a logical operand or between two integer operands
will be integer. The kind type parameter of the result will be the same as
the larger kind parameter of the two operands. If the operands have the same
kind parameter, the result has the same kind parameter.
- When you use the -qlog4 compiler option and the default integer
size is INTEGER(4), logical results of logical operations will have
type LOGICAL(4), instead of LOGICAL(n) as specified in the
table above. If you specify the -qlog4 option and the default integer
size is not INTEGER(4), the results will be as specified in the table
above.
- When you specify the -qctyplss compiler
option, XL Fortran treats character constant expressions as Hollerith constants.
If one or both operands are character constant expressions, the data type
and the length of the result are the same as if the character constant expressions
were Hollerith constants. See the "Typeless" rows in the previous tables for
the data type and length of the result.
See XL Fortran Compiler-Option Reference in the XL Fortran Compiler Reference for information about compiler options.
End of IBM Extension
IBM Extension
Using BYTE data objects
Data objects of type BYTE can be used wherever a LOGICAL(1), CHARACTER(1), or INTEGER(1) data object can be used.
The data types of BYTE data objects are determined by the context
in which you use them. XL Fortran does not convert them before use. For example,
the type of a named constant is determined by use, not by the initial value
assigned to it.
- When you use a BYTE data object as an operand of an arithmetic,
logical, or relational binary operator, the data object assumes:
- An INTEGER(1) data type if the other operand is arithmetic, BYTE, or a typeless constant
- A LOGICAL(1) data type if the other operand is logical
- A CHARACTER(1) data type if the other operand is character
- When you use a BYTE data object as an operand of the concatenation
operator, the data object assumes a CHARACTER(1) data type.
- When you use a BYTE data object as an actual argument to a procedure
with an explicit interface, the data object assumes the type of the corresponding
dummy argument:
- INTEGER(1) for an INTEGER(1) dummy argument
- LOGICAL(1) for a LOGICAL(1) dummy argument
- CHARACTER(1) for a CHARACTER(1) dummy argument
- When you use a BYTE data object as an actual argument passed
by reference to an external subprogram with an implicit interface, the data
object assumes a length of 1 byte and no data type.
- When you use a BYTE data object as an actual argument passed
by value (VALUE attribute), the data object assumes an INTEGER(1) data type.
- When you use a BYTE data object in a context that requires a
specific data type, which is arithmetic, logical, or character, the data object
assumes an INTEGER(1), LOGICAL(1), or CHARACTER(1) data
type, respectively.
- A pointer of type BYTE cannot be associated with a target of
type character, nor can a pointer of type character be associated with a target
of type BYTE.
- When you use a BYTE data object in any other context, the data
object assumes an INTEGER(1) data type.
End of IBM Extension