Bug 50975 - Logical operators evaluated in wrong order if no side effects
Summary: Logical operators evaluated in wrong order if no side effects
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.6.2
: P3 major
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-11-03 07:19 UTC by Jeremy
Modified: 2011-11-03 21:08 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jeremy 2011-11-03 07:19:01 UTC
gcc 4.6.2  -Os 

If the expressions either side of a logical operator (|| or &&) have no
side effects, gcc sometimes evaluates them in the wrong order.    See
the example below.  Of course the code works, but the standard is clear,
logical operators GUARANTEE left to right evaluation.  In this case 
people use the feature as a micro optimization, putting the most likely to succeed case first with || or vice-versa with &&.

-----------------------------------
#include <stdio.h>
int
main( int argc, char *argv[] )
{
  char *last = argv[1];

  if( *last == 10 || *last == 13 )
    --last;

  printf("last = %p\n", last );
  return 0;
}
---------------------------------------------
    movb    (%eax), %dl # *last_3, D.2517
    cmpb    $13, %dl    #, D.2517
    je  .L4 #,
    cmpb    $10, %dl    #, D.2517
    jne .L2 #,
.L4:
    decl    %eax    # last
.L2:
--------------------------------------------
Comment 1 Richard Biener 2011-11-03 08:26:33 UTC
But ... you can't tell the difference.  So this is a valid optimization.
Comment 2 Jeremy 2011-11-03 12:37:41 UTC
(In reply to comment #1)
> But ... you can't tell the difference.  So this is a valid optimization.

You can tell the difference in execution time.

And why is this an "optimization"?  In this case, I cant see how it can improve the code other than to lose any input from the programmer, who knows when the data is biased.  I guess it might help in a more complex expression.

I think this is different from the controversy over the handling of signed integer overflow.  There is no undefined behavior here.  The language standard from K&R to the present day explicitly states the evaluation order is guaranteed left to right with these operators.
Comment 3 Eric Botcazou 2011-11-03 21:08:43 UTC
> You can tell the difference in execution time.

Execution time isn't a side effect of the abstract machine as defined by the ISO C standard.  5.1.2.3 reads:

1 The semantic descriptions in this International Standard describe the behavior
  of an abstract machine in which issues of optimization are irrelevant.

As long as the side-effects are preserved ("as if" rule), this is valid.

> I think this is different from the controversy over the handling of signed
> integer overflow.  There is no undefined behavior here.  The language standard
> from K&R to the present day explicitly states the evaluation order is
> guaranteed left to right with these operators.

Only if there are side-effects, otherwise the "as if" rule can be applied.