EDIT: Гаразд, зрозумів.
Перше, що слід сказати, це те, що очевидно, ви все одно не повинні використовувати цей код. Однак, коли ви розширюєте її, вона стає еквівалентною:
j = j ^ (i = i ^ (j = j ^ i));
(Якби ми використовували більш складний вираз, такий як foo.bar++ ^= i
, було б важливо, щоб його ++
оцінювали лише один раз, але тут я вважаю, що це простіше.)
Тепер порядок оцінки операндів завжди зліва направо, тому для початку отримаємо:
j = 36 ^ (i = i ^ (j = j ^ i));
Це (вище) є найважливішим кроком. Ми отримали 36 як LHS для операції XOR, яка виконується останньою. LHS не є "значенням j
після оцінки RHS".
Оцінка RHS значення ^ включає вираз «вкладений на один рівень», тому воно стає:
j = 36 ^ (i = 25 ^ (j = j ^ i));
Потім, дивлячись на найглибший рівень вкладеності, ми можемо підставити обидва i
і j
:
j = 36 ^ (i = 25 ^ (j = 25 ^ 36));
... що стає
j = 36 ^ (i = 25 ^ (j = 61));
Присвоєння j
в RHS відбувається спочатку, але результат у будь-якому випадку перезаписується в кінці, тому ми можемо проігнорувати це - немає подальших оцінок j
до остаточного призначення:
j = 36 ^ (i = 25 ^ 61);
Зараз це еквівалентно:
i = 25 ^ 61;
j = 36 ^ (i = 25 ^ 61);
Або:
i = 36;
j = 36 ^ 36;
Що стає:
i = 36;
j = 0;
Я думаю, що це все правильно, і це діходить до правильної відповіді ... вибачення перед Еріком Ліппертом, якщо деякі деталі щодо замовлення на оцінку трохи не відповідають