Next: , Previous: Context-Sensitive Constants, Up: Non-bugs


15.5.5 Equivalence Versus Equality

Use of .EQ. and .NE. on LOGICAL operands is not supported, except via -fugly-logint, which is not recommended except for legacy code (where the behavior expected by the code is assumed).

Legacy code should be changed, as resources permit, to use .EQV. and .NEQV. instead, as these are permitted by the various Fortran standards.

New code should never be written expecting .EQ. or .NE. to work if either of its operands is LOGICAL.

The problem with supporting this “feature” is that there is unlikely to be consensus on how it works, as illustrated by the following sample program:

     LOGICAL L,M,N
     DATA L,M,N /3*.FALSE./
     IF (L.AND.M.EQ.N) PRINT *,'L.AND.M.EQ.N'
     END

The issue raised by the above sample program is: what is the precedence of .EQ. (and .NE.) when applied to LOGICAL operands?

Some programmers will argue that it is the same as the precedence for .EQ. when applied to numeric (such as INTEGER) operands. By this interpretation, the subexpression `M.EQ.N' must be evaluated first in the above program, resulting in a program that, when run, does not execute the PRINT statement.

Other programmers will argue that the precedence is the same as the precedence for .EQV., which is restricted by the standards to LOGICAL operands. By this interpretation, the subexpression `L.AND.M' must be evaluated first, resulting in a program that does execute the PRINT statement.

Assigning arbitrary semantic interpretations to syntactic expressions that might legitimately have more than one “obvious” interpretation is generally unwise.

The creators of the various Fortran standards have done a good job in this case, requiring a distinct set of operators (which have their own distinct precedence) to compare LOGICAL operands. This requirement results in expression syntax with more certain precedence (without requiring substantial context), making it easier for programmers to read existing code. g77 will avoid muddying up elements of the Fortran language that were well-designed in the first place.

(Ask C programmers about the precedence of expressions such as `(a) & (b)' and `(a) - (b)'—they cannot even tell you, without knowing more context, whether the `&' and `-' operators are infix (binary) or unary!)

Most dangerous of all is the fact that, even assuming consensus on its meaning, an expression like `L.AND.M.EQ.N', if it is the result of a typographical error, doesn't look like it has such a typo. Even experienced Fortran programmers would not likely notice that `L.AND.M.EQV.N' was, in fact, intended.

So, this is a prime example of a circumstance in which a quality compiler diagnoses the code, instead of leaving it up to someone debugging it to know to turn on special compiler options that might diagnose it.