bellow is simple code that express this bug: /************ * File : b.C ************/ #include <stdio.h> int main() { int a = 1; printf(" a = %i \n",(a++)+(++a)); //4 a = 1; printf(" a = %i \n",(a++)+(a++)+(++a)); //4 return 0; } After compilation in a following way: c++ -o b b.C The result was: a = 4 a = 4
Not a bug in gcc but rather in your code. Read about sequence points and modifying variables between them.
*** Bug 15012 has been marked as a duplicate of this bug. ***
*** Bug 15103 has been marked as a duplicate of this bug. ***
*** Bug 14417 has been marked as a duplicate of this bug. ***
*** Bug 13403 has been marked as a duplicate of this bug. ***
*** Bug 12552 has been marked as a duplicate of this bug. ***
*** Bug 11363 has been marked as a duplicate of this bug. ***
*** Bug 17018 has been marked as a duplicate of this bug. ***
*** Bug 14951 has been marked as a duplicate of this bug. ***
*** Bug 16887 has been marked as a duplicate of this bug. ***
*** Bug 816 has been marked as a duplicate of this bug. ***
*** Bug 4978 has been marked as a duplicate of this bug. ***
*** Bug 5724 has been marked as a duplicate of this bug. ***
*** Bug 6790 has been marked as a duplicate of this bug. ***
*** Bug 7135 has been marked as a duplicate of this bug. ***
*** Bug 9693 has been marked as a duplicate of this bug. ***
*** Bug 16309 has been marked as a duplicate of this bug. ***
*** Bug 10947 has been marked as a duplicate of this bug. ***
*** Bug 17095 has been marked as a duplicate of this bug. ***
*** Bug 17253 has been marked as a duplicate of this bug. ***
*** Bug 17282 has been marked as a duplicate of this bug. ***
Volker recently added a small paragraph about this very common non-bug to our non-bug page: http://gcc.gnu.org/bugs.html#nonbugs_c You can read here about this bug.
*** Bug 17507 has been marked as a duplicate of this bug. ***
*** Bug 17639 has been marked as a duplicate of this bug. ***
*** Bug 19798 has been marked as a duplicate of this bug. ***
*** Bug 20181 has been marked as a duplicate of this bug. ***
The point I was making with my example is that the native types (int, long, char, etc...) have different behaviour than a user-defined class with the operator++. If it is compiler dependent which way the expression is evaluated, why not at least make them both agree? GCC is also the only compiler out of the 5 that I've tested that exhibits this behaviour... all others unify the behaviour of native and user-defined operator++.
(In reply to comment #28) The code is undefined, which means we should be able to do system("rm -Rf /");, note we don't.
Here is a better clarification: Case 1 ====== int a = 0; int b = a++ + a++; printf("b = %d\n", b); // output is 0 Case 2 ====== class A { int a_; public: A() : a_(0) {} int operator++() { return a_++; } }; A a; int b = a++ + a++; printf("b = %d\n", b); // output is 1 This is a simple case that shows how the behaviour of the operator++ should be united. I'm not sure what you mean by the system(...) call... I understand that the code is undefined (meaning its up to the compiler vendor to implement as they see fit). I think the most fitting way is to have the above two cases unified in behaviour... isn't one of the reasons that operators were added to C++ was to allow user-defined types to mimic the functionality and usability of the native C types?
(In reply to comment #30) > I'm not sure what you mean by the system(...) call... I understand that the code > is undefined (meaning its up to the compiler vendor to implement as they see > fit). I think the most fitting way is to have the above two cases unified in > behaviour... isn't one of the reasons that operators were added to C++ was to > allow user-defined types to mimic the functionality and usability of the native > C types? Undefined means that we can do anything. Which where the system call comes from. The point is that this undefined, there does not even have be a constancy in the behavior across optimization levels, types or anything else.
I won't press the issue further because I have other things more pressing ;) But I think the decision to not change the behaviour here is wrong. I cannot create an Integer class that acts as an int due to the operator++. Just because it is undefined does not mean that we have to arbitrarily have to choose a method that adds no value over one that adds good value. Nearly all other compiler vendors have adopted this method since it has an element of common-sense in the face of an undefined process. I get the feeling that the only reason it isn't changed is simply because no-one wants to do it. If there is another reason, what is it?
Although I can confidently say that I've been less than enthusiastic with some of GCC's standards interpretations; here GCC's results in each of the examples you cite are within the set of semantically consent values which should be expected to result from an unspecified evaluation and/or value assignment order. (Although do agree that GCC has no license to return any value other than those which would result from these ordering ambiguities). (Although do believe that GCC should adopt an lr evaluation order; as expressions which are otherwise ambitious are useless, and those which are unaffected are insensitive to it; resulting in no harm, only benefit; and with a little luck may lead to the C/C++ committees coming to their senses in time.)
*** Bug 3165 has been marked as a duplicate of this bug. ***
*** Bug 1039 has been marked as a duplicate of this bug. ***
*** Bug 2550 has been marked as a duplicate of this bug. ***
*** Bug 3324 has been marked as a duplicate of this bug. ***
*** Bug 5159 has been marked as a duplicate of this bug. ***
*** Bug 5494 has been marked as a duplicate of this bug. ***
*** Bug 5516 has been marked as a duplicate of this bug. ***
*** Bug 6409 has been marked as a duplicate of this bug. ***
*** Bug 9334 has been marked as a duplicate of this bug. ***
*** Bug 9675 has been marked as a duplicate of this bug. ***
*** Bug 21246 has been marked as a duplicate of this bug. ***
*** Bug 21404 has been marked as a duplicate of this bug. ***
*** Bug 22248 has been marked as a duplicate of this bug. ***
*** Bug 24015 has been marked as a duplicate of this bug. ***
*** Bug 1570 has been marked as a duplicate of this bug. ***
*** Bug 762 has been marked as a duplicate of this bug. ***
*** Bug 5051 has been marked as a duplicate of this bug. ***
*** Bug 8175 has been marked as a duplicate of this bug. ***
*** Bug 6765 has been marked as a duplicate of this bug. ***
*** Bug 6891 has been marked as a duplicate of this bug. ***
*** Bug 2673 has been marked as a duplicate of this bug. ***
*** Bug 26060 has been marked as a duplicate of this bug. ***
*** Bug 26418 has been marked as a duplicate of this bug. ***
*** Bug 26642 has been marked as a duplicate of this bug. ***
referring to duplicate 26642: The behavior changed between gcc3 and gcc4 and the comment is "there is no reason the result should not change"? Sorry, but I think that's a really bad way to handle things. When a update changes behavior, there should be et least an appropriate warning. And another comment says "look at the warning you got". If you'd read the warnings you would have seen it refers to that part of the code that didn't change its behavior. So a code that only uses the array-version (that behaves differently) wouldn't get the warning. I really doubt that there is any good reason that simple variables and array variables should differ in the order their expressions are solved. Please, think about it. At least give a warning at the right place!
(In reply to comment #61) > referring to duplicate 26642: > > The behavior changed between gcc3 and gcc4 and the comment is "there is no > reason the result should not change"? Why this is undefined code :).
(In reply to comment #61) > referring to duplicate 26642: > > The behavior changed between gcc3 and gcc4 and the comment is "there is no > reason the result should not change"? There is simply no guarantee at all that the behavior of this will or won't change. It's undefined code. It could change depending on the phase of the moon. > > Sorry, but I think that's a really bad way to handle things. When a update > changes behavior, there should be et least an appropriate warning. Unfortunately, it is impossible to warn for every permuation of undefined code at compilation time. However, in general, if you write code whose semantics are undefined, you are going to get burned. This is just the way the ball bounces.
*** Bug 26730 has been marked as a duplicate of this bug. ***
*** Bug 26820 has been marked as a duplicate of this bug. ***
*** Bug 26923 has been marked as a duplicate of this bug. ***
*** Bug 27153 has been marked as a duplicate of this bug. ***
*** Bug 27233 has been marked as a duplicate of this bug. ***
*** Bug 27344 has been marked as a duplicate of this bug. ***
*** Bug 27646 has been marked as a duplicate of this bug. ***
*** Bug 30935 has been marked as a duplicate of this bug. ***
*** Bug 31398 has been marked as a duplicate of this bug. ***
*** Bug 32067 has been marked as a duplicate of this bug. ***
*** Bug 32133 has been marked as a duplicate of this bug. ***
*** Bug 32536 has been marked as a duplicate of this bug. ***
*** Bug 33043 has been marked as a duplicate of this bug. ***
*** Bug 33248 has been marked as a duplicate of this bug. ***
*** Bug 33270 has been marked as a duplicate of this bug. ***
*** Bug 37800 has been marked as a duplicate of this bug. ***
*** Bug 38516 has been marked as a duplicate of this bug. ***
*** Bug 39143 has been marked as a duplicate of this bug. ***
*** Bug 40366 has been marked as a duplicate of this bug. ***
*** Bug 42711 has been marked as a duplicate of this bug. ***
For the good expansion order make a step by step working Like when go for the buying of the juicer/blender http://zinch.zendesk.com/entries/31114770-Locating-Smoothie-Makers-In-Low-price customer feedback is the key of the success. So For the right order of the expansion an expert advice can work better for you.
Is this produces correct output? #include <cstring> #include <cstdio> int main() { int i = 100; i = i++ + ++i; printf("i=%d\n", i); i = 100; i = ++i + i++; printf("i=%d\n", i); i = 100; i = i + i++; printf("i=%d\n", i); return 0; } output: i=202 i=203
Dear Oleg, You have three printf, but only 2 outputs. You don't tell us, what the right output should be, and why. Your tests are highly dependent on the order of evaluation. So the only use is to detect exactly this order of evaluation. This order is highly dependent on versions and platforms and lots of settings and configurations, which you did not specify. I'd say you should define your point more exactly. Yours nobs