FC2ブログ

singned charのswitch その2

ちょっと整理して書く。
signed char a = -128;
switch (a) {
case -128: // (1)
break;
case 128: // (2)
break;
default:
break;
}

このコードをコンパイル/実行してみる。
処理系     コンパイル結果         実行結果
gcc-3.4.6 warning (1)
g++-3.4.6 Error(ラベルが重複) -
gcc-4.6.3 warning (1)
g++-4.6.3 warning (1)

warningはいずれも、ラベルの最大値がswitchの式が取り得る値を超えているというもの。
g++-3.4.6だけはラベルの値ををswitchのsigned charにキャストした値で比較しようとしているため、-128と128が同値であるとしてエラーとしている。

エラーが出るならまだ許せるのだけれど、
これを下のように書き換えると、g++でもエラーが出ないわけだが・・・
signed char a = -128;
switch (a) {
case 128: // (1)
break;
default: // (2)
break;
}

これをコンパイル・実行してみると
処理系     コンパイル結果         実行結果
gcc-3.4.6 warning (2)
g++-3.4.6 warning (1)
gcc-4.6.3 warning (2)
g++-4.6.3 warning (2)

と、g++-3.4.6でも他と同じwarningを出すにも関わらず、着地点が異なる。これは困る。

いずれの場合もwarningやエラーが出た時点で、ラベルの値が不適当であると気がついて直してくれればいいだけの話であるのだけれども。
なんとも不思議な結果に相成りましたと。
g++-4.6.3以前に変更されているのか、g++-3の時点でpatchが出てるのかどうかも未確認。gccとg++でなぜ動作が異なっちゃったのかも不明。
誰ぞ知ってる方が居られましたらコメント下さい。

今時まだg++-3を使ってる環境は無さげなのだが、Cygwinではまだg++-3が現役なので、気をつけられたし。
ちゃんと型を意識して書けばいいだけなんだが。
スポンサーサイト

signed charのswitch

どうも以前は期待通りの動きをしていたっぽいコード。
現在の環境(gcc 4.6)ではdefaultに落ちる。
signed char a = '\x80';
switch (a) {
case 0x80:
puts("0x80");
break;
default:
puts("no match");
break;
}

符号付きcharなのでaの値は-128
だから、caseで書くとしたら、
case -128:
もしくは
case '\x80':
とすべきなんだけれど、どうもこれが0x80に落ちてたっぽい。
古いgccで検証すべきなんだけれども、面倒なのでパス。
仕様を探すも検索キーワードがなかなかしっくりさせられなくて検索できず。gcc3あたりだと0x80に落ちるのかなぁ・・・ちうかこういうコードが存在するってのが、移行を考えるととっても怖い。

#2012/06/11
0x80で処理できちゃうのはg++-3.4.6だった。gcc-3.4.6ではアンマッチとなる。
んー、バグ報告をさらってるんだけれど見つけられず。g++4までは放置だったのかなぁ。
プロフィール

f_yamaki

Author:f_yamaki

アクセスカウンタ
最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
カテゴリー
ブロとも申請フォーム

この人とブロともになる

ブログ内検索
RSSフィード
リンク