https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85599
--- Comment #9 from Steve Kargl <sgk at troutmask dot apl.washington.edu> --- On Wed, May 02, 2018 at 08:53:27AM +0000, janus at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85599 > > --- Comment #4 from janus at gcc dot gnu.org --- > (In reply to kargl from comment #1) > > 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. > > > > Thanks for the standard quote, Steve. It certainly goes in > the right direction, but I feel like it's not quite to the point. > > Some other (possibly) relevant passages I found in the 2008 standard: > > ***** > 7.1.7 Evaluation of operands > 1 It is not necessary for a processor to evaluate all of the operands of an > expression, or to evaluate entirely each operand, if the value of the > expression can be determined otherwise. > ***** The above is actually the clause I went looking for, but I was short on time yesterday. I think that this is the one along with the description of evaluation of a logical expression that applies. > That also sounds like optimizing away the function call might be valid, but > then there is also this one: > > ***** > 7.1.4 Evaluation of operations > 2 The evaluation of a function reference shall neither affect nor be affected > by the evaluation of any other entity within the statement. > ***** You could be right in that this clause applies. I, however, tend to think that this is meant to prevent a side effect such as program foo integer i, j integer, external :: ping, pong common /ah/i i = 1 j = ping() + pong() ! ping() changes value of i print *, pong(), j ! which effects the output of pong() i = 1 j = pong() + ping() print *, pong(), j end program foo function ping() result(n) integer k common /ah/ k k = k + 1 n = 42 end function ping function pong() result(n) common /ah/ m if (m > 0) then n = m else n = 0 end if end function pong Yes, it is admittedly a contrived example. It is also possible for a compiler to replace j = 0 * ping() + pong() with simply j = pong() where ping() is never evaluated. I'll note that gfortran currently will evaluate ping(), but if ping() takes ages to compute it might be nice to have -ffrontend-optimize remove its evaluation. > What worries me most is that other compilers choose different implementations. > Can this kind of code really be processor-dependent? Yes, that is troublesome.