Bug 27344

Summary: associativity of * operator incorrect when compiled without optimization
Product: gcc Reporter: mike.clarkson
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: alexey, algorithmus, asokumar, av1474, bala, barnarr, behloul.younes, bmead15, buergel, carpman, chuchunxin, devnull, d_picco, eric.mcvicker, fuchsia.groan, gaurav_har, gcc-bugs, gcc, ggs, jandres, janis, jompo, krs, lid, lindahlb, lxg8906, mayer, mikaldaz, mike.clarkson, nakkore, nobs, pierre.van.de.laar_at_philips.com, qyang, ramiller, raoulgough, raphael.ribas, rglan, rjvbertin, robc, s9322036, SimonX200, smartmouse714, suan, super.aorta, svetozarmarkov, tczarnecki, vanveghel, vitaly, zshao
Priority: P3    
Version: 3.4.5   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

Description mike.clarkson 2006-04-27 23:53:14 UTC
Here is the version and system info:

% g++ -v
Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.5/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux
Thread model: posix
gcc version 3.4.5 20051201 (Red Hat 3.4.5-2)


Here is the output from the test program (which is included below)
% g++ -o associativityTest -O3 associativityTest.cpp
% ./associativityTest
neg_50 = -50
% g++ -o associativityTest associativityTest.cpp
% ./associativityTest
neg_50 = 50

You can see the different answers above, as a result of compiling with and without optimization. The answer of -50 is correct, based on the left to right associativity of the * operator.

Here is the test file associativityTest.cpp:

#include <iostream>

using namespace std;

class Int
{
public:
  explicit Int(int value)
    : _value(value)
  {
  }

  Int neg()
  {
    _value *= -1;
    return *this;
  }

  int value()
  {
    return _value;
  }

  Int operator*(Int right)
  {
    return Int(_value*right._value);
  }

private:
  int _value;
};

Int operator*(Int I, int i)
{
  return I*Int(i);
}

Int operator*(int i, Int I)
{
  return I*i;
}

int main()
{
  Int five(5);

  Int neg_50 = (five * 2 * five.neg());

  cout << "neg_50 = " << neg_50.value() << endl;
}
Comment 1 Andrew Pinski 2006-04-28 00:00:09 UTC
(five * 2 * five.neg());

This is equivlant to:
(five * 2) * (five.neg())
but the C and C++ standard do not specify which expression is evulated first.
In that (five * 2) might be evulated first or five.neg().  five.neg() has a side effect of changing five (_value *= -1;) which makes the above statement undefined as five is accessed and written to without a sequence point inbetween.


And it makes it a duplicate of PR 11751.

*** This bug has been marked as a duplicate of 11751 ***