The source code depicting the problem is attatched as a file. Lines which show existance of the bug: cout << a.set(5).get() << a.set(30).get(); cout << a.get(); The output of the compiled program: 5305 The machine code appears to be executeing 'set(5)' first, and then 'set(30)', as it should. However, as indicated by the last output, it executed 'set(5)' last as well as first. It appears to be executing 'set(5)' twice. The generated code should be of the following: operator<<(operator<<(cout, a.set(5).get()), a.set(30).get()); I ran over the output and code several times to figure out what order the operations are actually taking place, but I was unable to come up with a logical order that would produce the output, unless 'set(5)' was being executed twice. Release: 2.95.3 Environment: FreeBSD How-To-Repeat: The file attatched shows how to repeat.
Fix: There are two fixes: 1) Adjust the problem lines as so: cout << a.set(5).get(); cout << a.set(30).get(); cout << a.get(); 2) Inline the methods 'set(int)' and 'get()' Apply either fix and the output of the compiled program is as expected: 53030
State-Changed-From-To: open->feedback State-Changed-Why: I beleive the code is ill-formed. I agree the code is equivalent to operator<<(operator<<(cout, a.set(5).get()), a.set(30).get()); which I'll rewrite as Foo (Baz (cout a.Wibble (5)), a.Wobble (30))) There are 4 sequence points in that, each between evaluating the parameters to a call, and the call itself. These sequence points are partially ordered, but not completely ordered. In particular there is no ordering between the a.Wobble (30) call and the a.Wibble (5) call. i.e. in evaluating the argyments to Foo, I could a.Wobble (30) a.Wibble (5) cout call Baz call Foo I cout reorder the a.Wibble and a.Wobble calls. your example had a.Wobble (5).Fetch1 () and a.Wibble (30).Fetch2 (), those fetch calls are similarly unorderd. Provided the appropriate Fetch occurs after the Wibble/Wobble call, C++ semantics are maintained. Let me know if you disagree with my analysis
From: "Brian Lindahl" <lindahlb@hotmail.com> To: nathan@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org, lindahlb@hotmail.com, nobody@gcc.gnu.org, unifex@yuidesigns.net, gcc-gnats@gcc.gnu.org Cc: Subject: Re: c++/7135: Faulty Operator Precedence Date: Thu, 27 Jun 2002 11:47:27 -0700 First of all, I disagree with your analysis. One fact alone should contradict the analysis: Inlining the methods changes the compiler output, and thus, the output displayed on the screen. I believe that, according to C++ semantics, inlining a function should not change compiler output. I think the problem in my example was the naive expansion of the code from: cout << a.set(5).get() << a.set(30).get(); To: operator<<(operator<<(cout, a.set(5).get()), a.set(30).get()); In fact, I should have stated that the code should be equivalent to: operator<<( operator<<( cout, A::get( &A::set(5, &a) ) ), A::get( &A::set(30, &a) ) ); (Note the method, set, returns '*this' as a 'const A &') > There are 4 sequence points in that, each between > evaluating the parameters to a call, and the call itself. > These sequence points are partially ordered, but not > completely ordered. In particular there is no ordering As shown above, there are more than 4 sequence points, in evaluating the parameters of the parameters of the call. Furthermore, the existance of parenthesis creates a need, I believe, for complete ordering, not the partial ordering you suggest. > completely ordered. In particular there is no ordering > between the a.Wobble (30) call and the a.Wibble (5) call. Correct, in particular. But because they are contained in different layers of parenthesis, there is a complete ordering in the code. I hope I understood what you meant correctly, -Brian Lindahl _________________________________________________________________ Chat with friends online, try MSN Messenger: http://messenger.msn.com
State-Changed-From-To: feedback->closed State-Changed-Why: not a bug
From: Nathan Sidwell <nathan@codesourcery.com> To: Brian Lindahl <lindahlb@hotmail.com> Cc: nathan@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org, nobody@gcc.gnu.org, unifex@yuidesigns.net, gcc-gnats@gcc.gnu.org Subject: Re: c++/7135: Faulty Operator Precedence Date: Sun, 30 Jun 2002 10:47:40 +0100 Brian Lindahl wrote: > > First of all, I disagree with your analysis. One fact alone should > contradict the analysis: > Inlining the methods changes the compiler output, and thus, the output > displayed on the screen. > > I believe that, according to C++ semantics, inlining a function should not > change compiler output. all compiler optimizations are invariant on the abstract machined described by the std for well formed programs. But, I contend that your program is not well-formed, so a compiler assumption is broken, and hence optimizations may do anything. > In fact, I should have stated that the code should be equivalent to: > operator<<( > operator<<( > cout, > A::get( > &A::set(5, &a) > ) > ), > A::get( > &A::set(30, &a) > ) > ); > > (Note the method, set, returns '*this' as a 'const A &') > > > There are 4 sequence points in that, each between > > evaluating the parameters to a call, and the call itself. > > These sequence points are partially ordered, but not > > completely ordered. In particular there is no ordering > > As shown above, there are more than 4 sequence points, in evaluating the > parameters of the parameters of the call. Furthermore, the existance of > parenthesis creates a need, I believe, for complete ordering, not the > partial ordering you suggest. no it does not. function parameters may be evaluated in any order. the inner operator << call may be performed before or after the second a::get (a::set (30)) call. Hence the a::get (a::set ()) sequences are unordered wrt eachother. > Correct, in particular. But because they are contained in different layers > of parenthesis, there is a complete ordering in the code. no, you are incorrect. You cannot enforce evaluation ordering by adding parentheses. Anyway these parentheses are part of the function call syntax, and not the same as expression grouping parenthsese (and, more importantly), neither are those ','s comma operators. I am closing the PR. nathan -- Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC 'But that's a lie.' - 'Yes it is. What's your point?' nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
Reopening to mark as a duplicate of...
...PR 11751. *** This bug has been marked as a duplicate of 11751 ***