トップ «前の日記(2005年03月08日 (火)) 最新 次の日記(2005年03月10日 (木))» 編集

*Messages*

Search

書いてる人: しまだみつのぶ (aka. simm, saica)

最新情報URL: https://gouketsu.net/simm/d/

"8024402C"でたどり着かれた方はこちら: 「壁の内側からWindowsUpdateに失敗する


2005年03月09日 (水) [長年日記]

1 [comp] if ( (short)( x & 0xff00 ) > 0 )

会社で、コンパイル時に最適化オプション(-O2)をつけたら挙動がおかしくなる、という現象が発生した。原因を調べた人が「どうも条件判定が怪しい」と言ったので、該当部分(この項目のタイトルにあるif文)についていろいろ試してみた。

まず、問題になってる環境を確かめたところ、RedHat Linux 9 の gcc-3.2.2 らしい。そこで、同じ gcc-3.2.2 がインストールしてある FreeBSD 4.7-Release5.1-Release で

#include <stdio.h>

short minus(int num)
{
  return ( num & 1 ) ? 0xff00 : 0xf000;
}

int main (int ac, char** av)
{
  short x = minus(ac);
  if ( (short)( x & 0xff00 ) > 0 ) {
    printf( "PLUS\n" );
  } else {
    printf( "MINUS\n" );
  }
  return 0;
}

というソースをコンパイルし、実行。

  • 最適化なし: "MINUS"
  • -O1,-O2: "PLUS"

が表示された。0xff00 の部分を -256 に書き換えても同じ結果。-O2つきでアセンブリコードを出力したところ、0xff00 のあたりは

testl $65280, %eax

となっていた。

次に、gcc-3.3.3 がインストールされている FreeBSD 5.1-Release5.2.1-Release 環境で同じことを試したところ、最適化オプションにかかわらず "MINUS" が表示された。同様にアセンブリコードを出力したところ、0xff00 のあたりは

testw $-256, %ax

となっていた。

他に、gcc-2.7 系や gcc-3.2.3 でも試したところ、最適化オプションにかかわらず "MINUS" が表示された。

結局、

gcc-3.2.2
定数 0xff00 は、無条件に 0x0000ff00 と解釈される
他のコンパイラ
定数 0xff00 が short と比較される際、0xff00 を short として扱う

という挙動っぽい。「他のコンパイラ」と書いたのは、gcc 以外ではこの問題が発生していないため。

それにしても、RedHat9 とか FreeBSD 4.7-Release 標準の gcc に、こんなバグが潜んでたのね…

2 [URL] Google サジェスト

isearchマンセー (謎)

しかし、(2005-03-09時点で)「あ」を入力したときに最初にでる候補は、相当批判をあびる、ゆーことになるだろうな (謎)

3 [rail] 乗車車両 (2005-03-09)

出勤

FL22(8921) → VH26(1126)

帰宅: 天理駅まで徒歩

L08(8358) → KL21(3221)

本日のツッコミ(全3件) [ツッコミを入れる]
1 へるみ (2005年03月10日 (木) 01:33)

vc6/vc7.1/bcc32/iccでMINUSと表示されました.<br>ただ,理由ですが,「0xff00をshortとして扱うから」ではなくgcc-3.2.2だと「intからshortへのcastが正しく動作していないから」が正確な気がします.定数値はint型で,short + intはintに格上げされてから加算されますので.<br>(例) short a = 30000; printf("a'=%d\n", a+30000);は-5536ではなく60000と表示される.

2 もりた1 (2005年03月10日 (木) 02:03)

そーでつね。

3 simm (2005年03月10日 (木) 16:26)

たしかに、通常の演算だと int に拡張されますね。ただ、今回のアセンブリコードを見る限り、(gcc-3.2.3/3.3.3 の -O2 は)16ビットで比較してるので、(結果として)この場合は short として扱ってるのかな、と。<br><br>ちなみに、ARM版gcc-2.95.2でクロスコンパイルしてリナザウで動かしてみたら、最適化オプションありなしにかかわらず "MINUS" でした。


Information

更新情報取得方法

*Messages* の更新情報取得には、antenna.lirs もしくは index.rdfをご利用ください。 豪傑アンテナLIRSからも取得可能です。