4

In javascript, if I write:

var a = 6;
var b = 4;
a ^= b ^= a ^= b;
console.log(a, b);

the result will be 0 6.
but if I write:

var a = 6;
var b = 4;
a ^= b;
b ^= a; 
a ^= b;
console.log(a, b);

the result will be 4 6. And it's correct.

Why this single-line way of XOR swapping in javascript does not work?
And why it works fine in C++?

1 Answers1

6

In JavaScript, expressions are evaluated left-to-right.

That means that your one-liner is evaluated like this:

   a ^= b ^= a ^= b;
=> a = a ^ (b = b ^ (a = a ^ b))
=> a = 6 ^ (b = 4 ^ (a = 6 ^ 4))
=> a = 6 ^ (b = 4 ^ 2)
=> a = 6 ^ 6 = 0
   b = 4 ^ 2 = 6

In C++, you're making unordered modifications to the same object so the program is undefined.

The moral of this is that clever code rarely is.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • 2
    Why is it unordered in C++? The operator itself has right-to-left associativity. – rozina Sep 16 '15 at 06:59
  • @rozina The value expression `a ^= b ^= a ^= b` is undefined behavior because it does not contain a sequence point but modified `a` two times. http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points has an in-depth answer with details. – Jens Sep 16 '15 at 07:02
  • @rozina Associativity concerns the order in which operators are applied. It does not affect the order of evaluation of an operator's operands. – molbdnilo Sep 16 '15 at 07:02
  • "The operator associativity rules define the order in which adjacent operators with the same precedence level are evaluated." [c++ operators](http://web.ics.purdue.edu/~cs240/misc/operators.html) . – rcgldr Sep 16 '15 at 07:11