What's happening with this expression? b = a + (a = a + 5)

a = 5
b = a + (a = a + 5)

result b = 15

Why the first 'a' do not changes after that (a = a + 5)? But why second one changes? What exactly is happening here by steps?


Solution 1:

Expressions are evaluated left to right - always, regardless of grouping. So it's equivalent to:

a = 5;

int lhs = a; // 5
int rhs = (a = a + 5); // Increments a by 5 (i.e. a=10), and rhs=10
b = lhs + rhs; // 15

So after this has executed, a will be 10. But that only happens after a has been evaluated for the first operand of the main addition, which is why the result is 15 rather than 20.

It's really important to understand the part about evaluation order not being the same as precedence. Consider this:

int x = First() + Second() * Third();

Precedence means that the multiplication applies to the results of calling Second() and Third() - but First() is still evaluated first. In other words, this statement is equivalent to:

int lhs = First();
int rhs = Second() * Third();
int x = lhs + rhs;

See Eric Lippert's blog post on predence, associativity and ordering for more details.

I would strongly advise against writing code like this though.

Solution 2:

Unlike C and C++, the order of evaluation of subexpressions are left to right in C#. That's why the expression

j= ++i + ++i ;   

has well defined behavior in C# while undefined in C and C++.

In expression

b = a + (a = a + 5)  

left a will be evaluated first, then a+5 is evaluated and assigned to a and after addition of both evaluated subexpression, b will have value 15.

Solution 3:

The expression is always evaluated from left to right & then assigned to whatever on left hand. As

  a = 5
  b = a + (a = a + 5)
\\b = 5 + (a = 5 + 5)
  b = 15