まつもと ゆきひろです

In message "Re: [ruby-list:46820] 整数が格納された二変数を一つの式でスワップするコードのふるまいについて"
    on Thu, 28 Jan 2010 04:02:37 +0900, m_takao <threewayhandshake / gmail.com> writes:

|昔、整数が格納された二変数を一時変数を使わずにスワップするという
|賢いコードのことを知りました。
|
|a = a ^ b
|b = a ^ b
|a = a ^ b
|
|このコードはCでもPHPでも、JavaでもRubyでもきちんと動きました。
|(例えばa=1, b=2のとき実行するとa=2, b=1となる)
|ところが、これを一つの式にまとめて
|
|a = a ^ (b = (a = a ^ b) ^ b)
|
|と書いたものは、JavaやRubyでは期待したようには動きませんでした。

評価順が異なるからではないでしょうか。Rubyではオペランドは左
から右に評価すると定められています。一方、Cでは評価順序は実装
依存です。

さて、上記のスワップをa,bそれぞれの値を変数を再利用しないで
表記すると、以下のようになります。

a1 = a0 ^ b0
b1 = a1 ^ b0
a2 = a1 ^ b1

同様に、ひとつの式にまとめた形式は

a2 = a0 ^ (b1 = (a1 = a0 ^ b0) ^ b0)

となり、元の形式に戻すと

a1 = a0 ^ b0
b1 = a1 ^ b0
a2 = a0 ^ b1  # ここが違う

です。CやPHPで期待通りに動作したのは、わりと偶然でしょう。

                                まつもと ゆきひろ /:|)