Never assume that eager or short-circuit evaluation of logical statements will occur in Fortran.
Fortran standards from Fortran I (1957) through Fortran 2018 do not mandate or prohibit short-circuit logic. That has resulted in some compilers (e.g. Gfortran) sometimes using short-circuit logic, while other compilers (Flang/PGI) do not use short circuit logic. This causes breakage when the programmer tests with one Fortran compiler handles compound logic with eager evaluation, but other compiler uses short-circuit evaluation.
Compiler Fortran short-circuit
Not short-circuiting (standard Fortran behavior)
- PGI (may segfault)
Short circuiting (non-standard behavior)
Proper handling of compound logic in Fortran
One should carefully avoid assumptions that either eager or short-circuit evaluation of compound logical statements will occur, because neither is guaranteed by any Fortran standard.
If one assumes eager evaluation of Fortran logical statements, this can cause breakage where a function that’s part of the statement has side effects.
For example, a function that modifies a module variable, or simply an
intent(inout) variable will find those variables unmodified if a compiler uses short-circuit logic.
Fix: break up the compound
if statement so that the function is always evaluated (e.g. just before the
Assumptions that short circuit evaluation occurs commonly causes breakage of
optional :: arg optional dummy arguments.
subroutine myfun(a,b) real, intent(inout) :: a real, intent(in), optional :: b ! don't do this! if (present(b) .and. b < 0) a = b*a ! instead, do this: if present(b) then if (b < 0) a = b*a endif