Open raehik opened 1 year ago
Good idea. Worth noting that test/EvalSpec.hs in fortran-vars has tests relating to this that show the shortcircuting behaviour is more powerful in an analysis setting.
Although it seems that short-circuiting behaviour is the exception rather than the norm when it comes to compilers: https://www.scivision.dev/fortran-short-circuit-logic/
A concise example from @dorchard that demonstrates short-circuiting changing behaviour:
program ShortCircuit
implicit none
logical :: k
if (.true. .OR. effects()) then
end if
if (.false. .AND. effects()) then
end if
contains
function effects()
logical :: effects
write(*,*) "HELLO"
effects = .false.
end function effects
end program ShortCircuit
gfortran -O0
prints HELLO
twice.
gfortran -O1
prints nothing.
Just a comment from a standards dweeb: Here's the relevant text from the Fortran 2018 standard:
10.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.
So, a programmer shouldn't rely on side effects in the RHS of .AND.
and .OR.
expressions.
The referenced link at scivision.dev has a statement that I believe is not correct.
Compilers not short-circuiting (standard Fortran behavior):
Gfortran -O0 NAG Intel
Short circuiting (non-standard behavior)
Gfortran -O1 or higher
Short-circuiting is indeed standard-conforming behavior. Just not common enough for programmers to avoid the pitfalls.
This was present in fortran-vars' evaluator. Currently, all arguments for functions and operators are eagerly evaluated. (I picked this because it was easier to write, since I couldn't find any relevant standards/expectations for compilers.) It would be straightforward to add a switch for selecting between short-circuit and eager-evaluation.
We would add the switch by extending the evaluator monad to include some
Reader
environment -- this was always the plan, we simply didn't have any config yet. Then the binary operator and function call evaluation code would be changed to inspect the current mode and provide the appropriate behaviour.