インクリメントの話
i = 0;
i = i++ + ++i;
これで i の中身はどうなるの?っていう話。
C言語(gcc)だと 3 で、JavaやJavaScriptだと 2 になった。
Cはアセンブリを見るとこうなってる。
movl $0, -12(%ebp) leal -12(%ebp), %eax incl (%eax) movl -12(%ebp), %edx leal -12(%ebp), %eax addl %edx, (%eax) leal -12(%ebp), %eax incl (%eax)
要するにこういうことをやってるみたい。
i = 0; i += 1; i = i + i; i += 1;
代入式の前後でインクリメントされてるっぽい。なんで代入が終わってからインクリメントしてるんだよ。他のコンパイラだと結果が変わる可能性もありそうだ。
一方、JavaやJavaScriptは内部で何をやってるかはわからないけど、普通に考えると
- i = i++ + ++i
- i++ + ++i を見る
- i++ を見る
- i の中身は 0 だから、2.の式は 0 + ++i になる。
- i をインクリメントして、i の中身は 1 になる。
- ++i を見る
- i をインクリメントして、i の中身は 2 になる。
- i の中身は 2 だから、2.の式は 0 + 2 になる。
- i = 0 + 2 で、i には 2 が代入される。
こうなるわけで、それと合ってるんだから、まあそうなってるんだろう。
Javaの言語仕様を読んだらそんなニュアンスだったから、たぶん合ってる。つーか前置は+や-と同じ扱いで後置は半ば特別扱いなのね。勉強になるわ。
インクリメントはややこしいから、定型文的に使うにとどめた方が良さそうだ。