0

In the JavaScript language

var a=3;
a += a -= a*a;  //-3

In the C language:

int a=3;
a += a -= a*a;  //-12
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • In C the result is undefined. In JS: https://es5.github.io/#x11.13.2 – Kijewski Oct 16 '15 at 02:27
  • 3
    your statement is equivalent to `a = a + (a = a - a*a) ;` - does that make it easier to understand – Jaromanda X Oct 16 '15 at 02:33
  • 1
    …wherein the inner (right) assignment doesn't really matter, because the variable is overwritten by the outer (left) assignment right away, so it's `a = a + (a - (a * a))` – Bergi Oct 16 '15 at 02:41
  • @Kay: Any references for your first statement? I'd like to add it in my answer. – Bergi Oct 16 '15 at 03:06
  • 1
    @Bergi, in C an expression like `a = a + (a = a - a * a)` might "fill in" the `a`s in any order whatsoever the compiler deems useful. `a = 3 + (a = 3 - 3 * 3)` or `a = a + (a = 3 - 3 * 3)` (assignment first) is both allowed. Compare https://en.wikipedia.org/w/index.php?title=Sequence_point&oldid=685791988#Sequence_points_in_C_and_C.2B.2B. Even lhs references can be evaluated before the rhs. – Kijewski Oct 16 '15 at 03:08
  • Thanks, that's what I suspected. – Bergi Oct 16 '15 at 03:25

2 Answers2

3

In JS, operands of an operator such as +, =, * or += are always evaluated left-to-right. So what happens here is, step by step:

var a = 3;             // a = undefined
a += (a -= a*a);       // a = 3
a = 3 + (a -= a*a);    // a = 3
a = 3 + (a = 3 - a*a); // a = 3
a = 3 + (a = 3 - 3*a); // a = 3
a = 3 + (a = 3 - 3*3); // a = 3
a = 3 + (a = 3 - 9);   // a = 3
a = 3 + (a = -6);      // a = 3
a = 3 + -6;            // a = -6
a = -3;                // a = -6
-3;                    // a = -3

In contrast, your C code does evaluate the left-hand side a only after the right-hand side operand is evaluated, at which point a has a value of -6, which is then added to itself. However, the C language leaves this as undefined behaviour and does not define an specific order for the evaluations, so you only experienced this as an artifact of your compiler. See @Kay's comments for details.

Kijewski
  • 25,517
  • 12
  • 101
  • 143
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
-2

JavaScript assignments traverse left to right.

You are telling JS:

3 += 3 = 6
6 -= 3*3 = -3

I can't think of a permutation of this that would result in -12...

Jonny Asmar
  • 1,900
  • 14
  • 16
  • That might have the same outcome, but is not what happens here. – Bergi Oct 16 '15 at 02:44
  • Btw, `var a = 3; a -= a*a; a += a` results in `-12` – Bergi Oct 16 '15 at 02:47
  • Touche -- your answer much more accurately describes what's going on here. Had to do some testing to make sure. I guess it's actually more accurate to say, however, that assignment operators in JS are evaluated right to left, no? – Jonny Asmar Oct 16 '15 at 22:39
  • [kinda](http://stackoverflow.com/a/18495990/1048572) :-) The assignments happening right-to-left is a side effect of the operators being evaluated left-to-right (outside-in). – Bergi Oct 17 '15 at 11:23