0

I would always expect that it works as described here: What is x after "x = x++"?

But when I tried to test it:

int x = 0;
x = x++;
printf("x = %d\n", x);

The result is not 0 as I would expect but 1. We tested it in VS2012 and g++ (version 4.7).

Note, that this code prints 0 as expected:

int x = 0;
int y = x++;
printf("y = %d\n", y);
Community
  • 1
  • 1
kovarex
  • 1,766
  • 18
  • 34
  • 4
    Because you are invoking UB. It can return literally anything it wants and still be correct. – Xarn Aug 21 '14 at 09:24
  • 2
    or not returning anything and summon nasal demons instead, for that matter. – T.C. Aug 21 '14 at 09:25
  • 2
    Because your expectations are wrong. That question is tagged 'java'; this question is tagged 'c++'. – CB Bailey Aug 21 '14 at 09:27
  • You should really not mix'n'compare languages until you are quite fluent in them. Java and C++ are very different. JavaScript is the best reference for such "comparisons". Would you believe that `0 == ""` is `true` ? In JavaScript yes. But would you expect it to be so in another language? Not. – quetzalcoatl Aug 21 '14 at 09:28
  • Java and C++ are different languages that happen to have some syntactic symbols in common. The meanings of those symbols often differ. – molbdnilo Aug 21 '14 at 09:29
  • To be honest, it seems that operators are not always treated as function calls, because this should be 0, because the assignment requieres result of post-increment operator which has to return the value of the input before making any change. This should result in no change (and if written as function calls, it has to). `assign(i, postinc(i))` for `int& assign(int& dst, int&& src)` and `int postinc(int& x)` – firda Aug 21 '14 at 11:10
  • Although marked as duplicated and resolved as UB, I have to disagree - see [this question and accepted answer](http://stackoverflow.com/questions/4638364/undefined-behavior-and-sequence-points-reloaded?rq=1) - talks about function calls ;) `i.operator += (i.operator++(1))` – firda Aug 21 '14 at 11:16
  • correction: `x.operator = (x.operator++(1))` – firda Aug 21 '14 at 11:24
  • Note for readers from the future; [since C++17 this changed](https://stackoverflow.com/questions/47702220/what-made-i-i-1-legal-in-c17) and now does give your expected results . – M.M Jan 19 '20 at 21:03

1 Answers1

12

Note that you are linking Java question, but you are writing in C++.

In C (and inherited in C++), x = x++; is undefined, because you are modifying x twice between two sequence points. This means that the code can do literally anything, including stealing money from your bank account and hiring hitmen to kill you, and the compiler is in the right.

Be glad that it only sets x to 1. :-)

Xarn
  • 3,460
  • 1
  • 21
  • 43
  • Why is this any different from `int postinc(int& i) { int x = i; i = i + 1; return x; } i = postinc(i)`? BTW: My GCC retunrns 0 for both C and C++ and whatever `-std=` I did try. – firda Aug 21 '14 at 11:05
  • So now I understand it, and it is specified here, in the Sequence points in C and C++: http://en.wikipedia.org/wiki/Sequence_point Overloaded operator acts as function and creates sequence point, so it matters if the operator is overloaded or native. – kovarex Aug 21 '14 at 11:33
  • @firda kovarex beat me to it. Basically function call introduces a sequence point (actually, those no longer exist in the language, but it is still the best approximation) and that piece of code is well formed. Just not useful. – Xarn Aug 21 '14 at 11:36
  • @Xarn: Not useful, but *has to return zero / original value* in C++ (don't know in C). Looks like C++ is getting better face. `a[i++] = i` is of course undefined (or unspecified) because the order of evaluating `i++` and `i` (read as fetch i) is not defined/specified. Am I wrong or is the answer [there](http://stackoverflow.com/questions/4638364/undefined-behavior-and-sequence-points-reloaded?lq=1) bad? – firda Aug 21 '14 at 11:41
  • @kovarex: My Cygwin `GCC 4.8.3` 32bit returns zero for `int x = 0; x = x++; printf("%d", x);` ;) – firda Aug 21 '14 at 11:43
  • @firda Depends what you mean by bad. It says that if you have user defined type, then `I += ++I;` is defined, which is as far as I know correct. But things like this [`someInstance.Fun(++k).Gun(10).Sun(k).Tun();`](http://stackoverflow.com/questions/4709727/is-this-code-well-defined) are not, because the arguments to the function calls themselves are not sequenced. This means that simple `a[i++] = i;` invokes the same problems. (Two function calls involving modifying the same argument) – Xarn Aug 21 '14 at 11:58
  • @Xarn: but `x = x++` is different, it is `x.operator = (x.operator ++(1))` where `x` is `int&`. There is no problem with evaluation order and thus it *has to* preserve the value (if operators are trully treated as function calls, which *is* suggested in the answer there). I do understand your other examples, same as mine, same as `x = x + x++` - again undefined order of fetch/load vs. increment. Note that `x = x++` is like `*p = (*p)++`, there is no problem, well-defined in newest C++ standard. The increment is sequenced-before the assignment, because the assignmenet is dependent on it. – firda Aug 21 '14 at 12:08
  • @firda The *value computation* of `x++` is sequenced before the assignment. The *side effect* of `x++` is unsequenced relative to the assignment, and so the behavior is undefined. – T.C. Aug 21 '14 at 12:13
  • @T.C.: I really do not understand that. Maybe I should open my own question. Is the accepted answer [there](http://stackoverflow.com/questions/4638364/undefined-behavior-and-sequence-points-reloaded?lq=1) correct or incorrect? In either case, is `i = postinc(i)` different from `i = i++`? Why? Can *side-effect* of the function call be unsequenced? – firda Aug 21 '14 at 12:19
  • [3)](http://en.cppreference.com/w/cpp/language/eval_order) ...and ***side effect associated with*** any argument expression, or with ***the postfix expression designating the called function***, is sequenced before... Maybe it is in my english, what is the meaning of the word **designating**? Does it mean that the postfix (postincrement) is / can be the called function (we speak about) or does it mean something else? I can see that they talk about **built-in postincrement** in next point and later state that `i = i++ + 1` is undefined. Built-in postfix seems bad. – firda Aug 21 '14 at 14:24