-3

I am trying to swap 2 variables with an XOR operation.

int a = 5;
int b = 4;
a ^= b ^= a ^= b;

This code works in Objective-C and C++, but doesn't work in C# and JavaScript, and I can't understand the reason.

rmaddy
  • 314,917
  • 42
  • 532
  • 579

2 Answers2

2

This has to do with a slight difference in how C/C++ handle the op-assignment ( +=, ^= and others) operator compared to C# / Javascript.

In Javascript the variable(s) being assigned to do not change value until after the statement is completed. To simplify the math, suppose we have this code in Javascript:

var a = 5;
var b = 4;
a += b += a += b;

In javascript this sets a = 18 (a = 5 + 4 + 5 + 4) and b = 13 (b = 5 + 4 + 4). This is because of the fact that no variables change values until the whole statement has completed.

In contrast, in C/C++ variable assignment takes places when each subexpression of += takes place. Consider corresponding C code:

int a = 5;
int b = 4;
a += b += a += b;

This gives a = 22, which is obtained as follows: First the last part of the expression, a += b, is evaluated. This results in the value of 9. then b+= 9 is evaluated, giving b = 13. Then a+= 13 is evaluated giving a = 22. The value of b stands at 13.

  • There is no C/C++, and the code from OP is incorrect in most of the relevant standards, regardless of whether it appears to work. – Baum mit Augen Jul 31 '18 at 09:25
  • @BaummitAugen I do not agree that the code from OP is incorrect, it compiles without warning in some compilers (see for example https://onlinegdb.com/SJ-XSaaVQ ). From C/C++ perspective this is perfectly valid, although a bit terse and perhaps not very transparent. I found the question interesting, it is not obviously apparent why this behaviour is different across these languages. – Fridjon Gudjohnsen Jul 31 '18 at 11:19
  • @FridjonGudjohnsen It does not compile without waring if you use the right compiler and the right settings: https://wandbox.org/permlink/QOoFLGPw5PxMGETL It's certainly undefined behavior in C++03 and C++11 too I think. C++17 is unclear, and for C I lack the domain knowledge in the newer standards. Certainly not legal C90 though. – Baum mit Augen Jul 31 '18 at 11:24
  • @BaummitAugen I think this demonstrates a difference in C/C++ languages compared to C# / JavaScript and Java. C/C++ has for example ++a and --a operator that modifies variables before it's containing expression is evaluated. The same effect is in place with the += or ^= operators. BTW Op stated this to work in Objective C and it does compile there without warning. – Fridjon Gudjohnsen Jul 31 '18 at 12:09
  • @FridjonGudjohnsen Sure it does demonstrate a difference. But your claim that "this gives a = 22" and the explanation following it are still bogus for most standards (at least; I'm not even sure that changed for any standard). If you do this, the behavior of the *entire* program becomes undefined. 22 is as valid of a result as 0. – Baum mit Augen Jul 31 '18 at 12:17
0

Try using

a ^= b;
b ^= a;
a ^= b;

the chained assignments confuses C# and JS

Surt
  • 15,501
  • 3
  • 23
  • 39