1

Cの前置インクリメントの挙動がコンパイラによって違う

最近ゲーム制作の都合で、スクリプト言語を自作しています。
算術演算を一般的な言語の挙動と一致させるために、
インクリメントの挙動を確認していたら、面白い結果になったのでメモしておきます。

 

今回テストに使用したコード(jの値):

int i = 0, j = 0;
j = ++i + ++i + ++i;

Xcode(GCC)の結果: 7
VC++の結果: 9

 

一度の演算で同一の変数にインクリメントすると上記のように結果が変わってきます。
この原因は恐らく、
コンパイラが生成するアセンブリコードが違っているからではないかと勝手に解釈しています。
(残念なことに筆者はアセンブラを触った経験がないので、詳しくは分からないのですが)
コンパイラの演算の評価の仕方の違いでこのような差異が生まれるんだと思います。
具体的には以下のような評価をしているのではないかなぁと。

 

逆ポーランド記法による比較
GCCの評価 j,i,++,i,++,+,i,++,+,=
VC++の評価: j,i,++,i,++,i,++,+,+,=

 

VC++の場合、
インクリメントを演算子として評価しているので、こっちの方が実装が簡単です。
(GCCの挙動を見た段階で実装の判断をしてしまったので、結局難しい方で実装してしまいましたが)

まぁともあれ、どっちが一般的な挙動なんでしょうね。
本当にコンパイラによって結果が違うのであれば、
複数前置インクリメントを書くのはあまりおすすめできない方法と言えそうです。

ちなみに後置インクリメントの挙動は一致していました。

※追記
PHP5にて確認してみたところ、6というこれまた違う結果となりました。
恐らく評価順序はGCCと同様ですが、
iの加算処理を行った後スタックに積む際数値として処理しているんだと思います。

この結果から言語ごとに前置インクリメントの扱いは全く違うことが分かりましたので、
言語を自作する際は実装者の判断で決めてしまって問題ない、という事になりそうですね。

1

フィード

キーワード検索

最近の記事

最近のコメント

最近のトラックバック

カテゴリ

アーカイブ

ランキング