正しいのはどっち?

先日.netを最新バージョンにしたらはまったバグ。
void foo(void)
{
  if(0 != func()){
    error();
  }
}
char func(void)
{
  return (0);
}
という感じのプログラムで、何故か0を返しているのにerror()が実行されるという現象に出会った。
問題のソースは10数年以上、プレステやらプレステ2やらXBOXやらで使われて正常動作し続けてきたソースなので、こんなショボイ不具合が起こるわけがない。
これは最新の.netが何かおかしいのだろうか?と思い調べていたらなんとこんな行が!
extern int func(void);
本来char型の返り値の所を、externでint型として宣言してた!
つまり返り値として保証されているのは1byteだけで、その他上位3byteは保証されていない値だったため、ゴミ部分を読んで0以外の値と認識してしまっていたのだ。
ここで疑問なのは、果たしてこの挙動はコンパイラとして正しいのだろうか?
今まで10数年間問題なかったとはいえ、ただ単にまぐれで動いていただけかもしれないが、charだろうがintだろうが入ってる数値が変わるのはおかしいという気もする。
まぁどっちみちwarning出てるから、値は保証されないというのが正しいのかなぁ。ほんとは.netのせいにしたいけどw
後の人が苦労するので、warningはちゃんと潰しておこうね。

関連記事

カテゴリー: 未分類 パーマリンク

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)