Почему swap с xor отлично работает в С++, а в Java нет? какая-то головоломка

Возможный дубликат:
Почему этот оператор не работает в java x ^= y ^= x ^= y;

Образец кода

int a=3;
int b=4;
a^=(b^=(a^=b));

В c++ переменные меняются местами, а в java мы получаем a=0, b=4 почему?


person Andrei N    schedule 12.10.2010    source источник
comment
Этого следует избегать на таком высоком уровне: en.wikipedia.org/wiki/   -  person JoshD    schedule 12.10.2010


Ответы (2)


Записывая свой обмен в одном выражении, вы полагаетесь на побочные эффекты внутреннего выражения a^=b по отношению к внешнему выражению a^=(...). Ваши компиляторы Java и C++ работают по-разному.

Чтобы правильно выполнить замену xor, вы должны использовать как минимум два оператора:

a ^= b; 
a ^= (b ^= a);

Однако лучший способ поменять местами переменные — это сделать это обычным способом с временной переменной, и позволить компилятору выбрать лучший способ сделать это на самом деле:

int t = a;
a = b;
b = t;

В лучшем случае компилятор не будет генерировать вообще никакого кода для указанной выше подкачки и просто начнет обрабатывать регистры, содержащие a и b, наоборот. Вы не можете написать какой-либо хитрый код xor, который вообще не превосходит никакого кода.

person Greg Hewgill    schedule 12.10.2010
comment
Обратите внимание, что правильный обмен XOR не работает в крайнем случае, когда a и b являются одной и той же переменной. - person ; 12.10.2010
comment
+1 за более идеоматический способ замены переменных. - person ; 12.10.2010
comment
Как насчет этого утверждения: a = (b ^= a ^= b) ^ a; Поскольку побочные эффекты в Java хорошо упорядочены, это должно работать. - person Boyd Stephen Smith Jr.; 23.07.2013

Это также не гарантирует работу на С++. Это неопределенное поведение.

Вы должны сделать это в трех отдельных утверждениях:

a ^= b; 
b ^= a;
a ^= b;
person reko_t    schedule 12.10.2010
comment
Причина в том, что, не строго говоря, между двумя точками последовательности (например, a;) переменная не может изменяться более одного раза, чтобы избежать неопределенного поведения. - person Armen Tsirunyan; 12.10.2010