Evaluation of if statements

Evaluation of if statements

During the transition of a project from CVF to IVF I made an interesting observation which may cause problems in other programs as well. Take the following code snippet:
integer :: k, a(100)
if (k.eq.0 .or. a(k).eq.1) goto xxx
In all Fortran compilers I used since 1965 the logical expression of the if statement was evaluated from left to right,
that means, if k equals 0 the goto was executed before the second term after the .or. was evaluated. In IVF (V11.1) the sequence of evaluation is not necessary from left to right which leads to an error exception if the index k in array a is zero. This is probably not an error, just a deviating behavior which has to be kept in mind when constructing logical expressions for if statements.

7 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Quoting - rase

if (k.eq.0 .or. a(k).eq.1) goto xxx
In all Fortran compilers I used since 1965 the logical expression of the if statement was evaluated from left to right,

This question has been beaten to death on this forum. I'm inclined to believe the experts on CVF, even though some people have not been bitten by the belief stated above.
Over a similar period, the only compilers I have used which implemented a C style shortcut evaluation were those which actually translated to C intermediate code with explicit shortcut style. Primarily, this means f2c (often called f77 in linux distros prior to g77 usage).
We didn't push our luck with Microsoft CPM-80 Fortran; there were too many non-standard practices required at that time to add an unnecessary one. It was exciting enough making OS API calls by storing the address 5 in a variable and CALLing that variable.
The original SGI Fortran, like g77, was developed out of f2c, and may have shared characteristics other than run-time library compatibility. HPUX Fortran apparently shared left to right optimization rules literally with their C, and may have followed that frequently in compound conditionals, but we were well aware by then that such an assumption would be non-portable.

Steve may correct me on this

In FORTRAN the order of a logical expression is specified in a different manner than it is for C++

6.5.1  Summary_of_Interpretation_Rules.  The  order  in
          which   primaries   are  combined  using  operators  is
          determined by the following:

             (1) Use of parentheses

             (2) Precedence of the operators

             (3) Right-to-left interpretation of  exponentiations
                 in a factor

             (4) Left-to-right interpretation of  multiplications
                 and divisions in a term

             (5) Left-to-right interpretation  of  additions  and
                 subtractions in an arithmetic expression

             (6) Left-to-right interpretation  of  concatenations
                 in a character expression

             (7) Left-to-right interpretation of conjunctions  in
                 a logical term

             (8) Left-to-right interpretation of disjunctions  in
                 a logical disjunct

             (9) Left-to-right    interpretation    of    logical
                 equivalences in a logical expression

In

if (k.eq.0 .or. a(k).eq.1) goto xxx

The "k.eq.0" and the "a(k).eq.1" fall under (7) above.
Whereas the results from these portions of the expression full under (8).

(7) is evaluated first, then (8)

Do not assume that all compilers do NOT follow the rules the same way that all other compilers do NOT follow the rules (or that they NOT follow the rules).

Jim Dempsey

Best Reply

Jim, the text you cite is not from any Fortran standard I recognize - is that perhaps from C or C++?

Fortran's rule is as follows:

7.1.5.4.2 Evaluation of logical intrinsic operations
Once the interpretation of a logical intrinsic operation is established, the processor may evaluate any other
expression that is logically equivalent, provided that the integrity of parentheses in any expression is not violated.

(This quote is from F2008, but it is the same in earlier versions.)

In other words, no specified direction and no short-circuit evaluation.

CVF behaved exactly the same way. We used to get the same complaint for CVF. What you get is whatever the optimizer liked best.

Use nested IF-THEN if it matters to you.

Retired 12/31/2016

Quoting - Steve Lionel (Intel)
Jim, the text you cite is not from any Fortran standard I recognize - is that perhaps from C or C++?

Fortran's rule is as follows:

7.1.5.4.2 Evaluation of logical intrinsic operations
Once the interpretation of a logical intrinsic operation is established, the processor may evaluate any other
expression that is logically equivalent, provided that the integrity of parentheses in any expression is not violated.

By the way, it's possible to promote parallel evaluation of C or C++ compound conditionals, and drop the guaranteed left to right shortcut evaluation, by using the | and & operators in place of the usual || and &&, and being careful with parentheses. Even the loose K&R style evaluation still favored by compilers such as ICL isn't permitted to break it, so this gives a direct correspondence with Fortran rules (aside from the different precedence, or masking operations on non-boolean expressions, which you would see without parentheses). So, any statement of the C or C++ rules has to be more specific than Jim's quote.

I quoted from F77 (that came up first in the google search)

Jim

Quoting - jimdempseyatthecove

I quoted from F77 (that came up first in the google search)

Jim

Look a little further down in the F77 standard:

6.6.1 Evaluation of Operands.
It is not necessary for a processor to evaluate all of the operands of an expression if the value of the expression can be determined otherwise. This principle is most often applicable to logical express(ions, [the typo is in the web version but not the paper original]

I guess you may have had to have been there to be certain that "interpretation" in 6.5.1 didn't mean order of evaluation. Steve at least was present at discussions by people who were there and determined the subsequent wording.
Left to right interpretation rule did have a major effect on mixed data type expression evaluation, which up to then was an extension not covered by the standard:
a*i/j/b (with implicit data types) could no longer be interpreted the same as (i/j)*(a/b), as the compiler we used did, well beyond the introduction of f77 standard.

Leave a Comment

Please sign in to add a comment. Not a member? Join today