2015-09-16 4 views
4

В JavaScript, если я пишу:Почему однострочный обмен XOR не работает в Javascript, но работает на C++?

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

результат будет 0 6.
, но если я пишу:

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

результат будет 4 6. И это правильно.

Почему этот однострочный способ обмена XOR в javascript не работает?
И почему это прекрасно работает на C++?

+3

Я не уверен, что это технически обоснованный C++. – Veedrac

+1

Вы уверены, что единственное утверждение 'a^= b^= a^= b'; эквивалентно * трем * утверждениям 'a^= b; b^= a; a^= b; '? –

+6

В C++ он не определен. Если это работает, это просто совпадение. – molbdnilo

ответ

6

В JavaScript выражения вычисляются слева направо.

Это означает, что один вкладыш оценивается так:

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 

В C++, вы делаете неупорядоченные изменения к одному объекту, так что программа не определена.

Мораль этого в том, что умный код редко бывает.

+2

Почему он неупорядочен в C++? Сам оператор имеет ассоциативность справа налево. – rozina

+0

@rozina Значение выражения 'a^= b^= a^= b' является неопределенным поведением, потому что оно не содержит точки последовательности, но изменено' a' два раза. http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points имеет подробный ответ с подробностями. – Jens

+0

@rozina Ассоциативность относится к порядку применения операторов. Это не влияет на порядок оценки операндов оператора. – molbdnilo

 Смежные вопросы

  • Нет связанных вопросов^_^