2

I have a simple code snippets which shows different behavior when build using C++ compiler and C# compiler.

C#

static void Main(string[] args)
{
   int i = 0;
   i += i++;
   Console.WriteLine(i);
   Console.ReadLine();
}

The result of i is 0. Copied from this link. For i = 0, why is (i += i++) equal to 0?

C++

int main() 
{
    int i = 0;
    i += i++;
    cout << i << endl;
}

The result of i is 1.

I just want to know why there is difference in code output in C# and C++.

Community
  • 1
  • 1
Muhammad Umar
  • 3,761
  • 1
  • 24
  • 36

2 Answers2

2

The designers of C# and C++ and C made different decisions about how to handle order of evaluation whereas in C# the order of evaluation if from left to right:

Operands in an expression are evaluated from left to right.

and side effects take place from left to right as well.

In C++ this is not the case, the draft C++ standard section 1.9 Program execution paragraph 15 says:

Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.

and if side effects on the same scalar object is sequenced relative to another side efect the result it undefined behavior:

[...]If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.[...]

and the draft gives examples of undefined behavior:

i = i++ + 1; // the behavior is undefined

which if we look at the expression from your code:

i += i++;

which is equivalent to:

i = i + i++ ;

we can now clearly see it invokes undefined behavior which means the result is unpredictable and can not be relied on.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • +1 for clear picture. I accepted your answer as it has better explanation. – Muhammad Umar Mar 28 '14 at 19:54
  • @MuhammadUmar if you want to learn more about undefined behavior [Why are these constructs undefined behavior?](http://stackoverflow.com/questions/949433/why-are-these-constructs-undefined-behavior) and [Undefined Behavior and Sequence Points](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points) are good places to start. – Shafik Yaghmour Mar 31 '14 at 02:30
0

In C, an expression like i= i++; has an undefined behavior, and can evaluate to 0 or 1 (incrementing after evaluation of the whole expression or before the assignment are both possible).

This was a strange design decision, as apparently innocent and perfectly justified code can produce unexpected results, like sum= a[i++] + a[i++];. Strangely too, nobody seems to be bothered.

  • 1
    This is incorrect. the postfix ++ operator (ex: i++) has a very defined behavior. "++i" increments i and returns the new value, "i++" increments i and returns *the original value*. – Yves Dubois Mar 28 '14 at 13:39
  • @YvesDubois But the order of that expression with respect to other (possibly side effect inducing) expressions within the same statement is not defined. – Servy Mar 28 '14 at 13:49
  • I didn't say that ++ had an undefined behavior. I spoke of expressions containing it. http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points –  Mar 28 '14 at 13:52
  • @Servy There is a very strict order in which expression are evaluated. In both examples given, the results are in no way undefined. – Yves Dubois Mar 28 '14 at 13:54
  • Since it's undefined behavior, `int i = 0; i = i ++;` can even result in `42` as a result. Or cause the program to crash. – James Kanze Mar 28 '14 at 16:21
  • @YvesDubois Where do you get that from? The C++ (and the C) standard say exactly the opposite. – James Kanze Mar 28 '14 at 16:22
  • And I don't understand the down votes, since this is the correct answer. In C and in C++, `i = i ++;` has undefined behavior. – James Kanze Mar 28 '14 at 16:23
  • Thanks for the hand, @James. I did face this phenomenon years back, with MS and gnu compilers showing opposite behaviors. –  Mar 28 '14 at 16:28
  • @JamesKanze It's a simple matter of operation precedence. `++`has precedence over `+=` and is thus evaluated first. – Yves Dubois Mar 28 '14 at 16:33
  • @YvesDubois It has nothing to do with precedence. The C++ standard says explicitly that the behavior is undefined. (See §5/4 in C++03.) It always has---this goes back to the earliest days of C. – James Kanze Mar 28 '14 at 17:16
  • @JamesKanze Have any link to a copy? – Yves Dubois Mar 28 '14 at 17:27
  • Okay, I just got an epiphany and finally understand what the problem is. To say the result is undefined is a bit of an exaggeration, after `int i=0; i+=i++;`, `i` will always be equal to 0 or 1. It depends if the `+` operator is constructed to work as `operator+(int a, int b)` or `operator+(const int& a, const int& b)`. In the first case, the left-hand side is evaluated as 0 before the right-hand side (`i++`) is evaluated. In the second case the left-hand side is evaluated as "the variable i", thus the code uses it's current value. And if I'm to believe you **this is not standardized!?** – Yves Dubois Mar 28 '14 at 18:02
  • It is explicitly standardized as being undefined behavior. –  Mar 28 '14 at 18:06
  • @YvesDaoust I guess they don't want to mess around with possible compiler optimizations. After all, it's not as if standardizing it would break legacy code. (unless it depended on undefined behaviour) – Yves Dubois Mar 28 '14 at 18:13
  • For safety, compilers should raise warnings when such constructs are used. It is not always the case. –  Mar 28 '14 at 18:22
  • @YvesDubois It's not normally available for free, but I believe that there are some unofficial copies (probably of the final draft) floating around on the net. (I got mine because I was a "technical expert" for AFNOR.) – James Kanze Mar 28 '14 at 18:26
  • @JamesKanze as far as I know this [thread](http://stackoverflow.com/questions/81656/where-do-i-find-the-current-c-or-c-standard-documents) links to all the publicly available draft standards. For the most part you can usually get pretty close to the official standard. – Shafik Yaghmour Mar 28 '14 at 19:25