https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85599

kargl at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kargl at gcc dot gnu.org

--- Comment #1 from kargl at gcc dot gnu.org ---
(In reply to janus from comment #0)
> Consider the following test case:
> 
> 
> program lazy
> 
>    logical :: flag
> 
>    flag = .false.
>    flag = check() .and. flag      ! 'check' is executed as expected
>    flag = flag .and. check()      ! bug: 'check' is not executed
> 
> contains
> 
>    logical function check()
>       integer, save :: i = 1
>       print *, "check", i
>       i = i + 1
>       check = .true.
>    end function
> 
> end
> 
> 
> The problem here is that gfortran executes the function 'check' only once,
> although it should be executed twice AFAICS.
> 
> Optimizing out the function call might be valid for a PURE function, but for
> an impure one with side effects, I don't think this is allowed.
> 
> Both ifort and flang execute the function twice. For gfortran, the
> optimization level does not seem to influence the result: -O0 and -O3 behave
> in the same way.
> 
> I tried with gfortran versions 5, 6, 7 and 8, which all exhibit the same
> buggy behavior.

The behavior may not be buggy, and it's best not to depend
on side-effects.  From F2018,

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.

  Two expressions of type logical are logically equivalent
  if their values are equal for all possible values of their
  primaries.

With 'flag = .false.', gfortran can determine that 
check()'s return value is irrelevant.  So, the
the values of 'flag .and. check()' and 'flag' are
logically equivalent.

Note, 'check() .and. flag' is logically equivalent
to 'flag', but the standard does not require any order
in the evaluation of op1 and op2 in a binary operation.

Also, note that this is my interpretation.  I could
be wrong.

Reply via email to