04

01

[C言語] 汎整数拡張

2014.04.01(20:45)

以下の2つのブロックは1か所しか違わないが、それぞれ★が実行される(gcc-4.8.1)。

{
  unsigned char c = 0;
  if ((c-1) < 0) {
    printf("LINE%d true\n",__LINE__); // ★
  } else {
    printf("LINE%d false\n",__LINE__);
  }
}
{
  unsigned int c = 0;
  if ((c-1) < 0) {
    printf("LINE%d true\n",__LINE__);
  } else {
    printf("LINE%d false\n",__LINE__); // ★
  }
}

どうしてそうなるのか考えてみてほしい。








前者はcと1と0が汎整数拡張でintに変換されてから評価されるので、
(intの0 - intの1) < (intの0)と評価され、
(intの-1) < (intの0) は真になる。

後者ではunsigned intは汎整数拡張されずそのまま評価され、
演算の一方がunsigned intなら他方もunsigned intに変換されてから評価されるので、
(unsignedの0 - unsigned intの1) < (unsignedの0)と評価され、アンダーフローがおきて
(unsignedの0xffffffff) < (unsignedの0) は偽になる。

興味を持った方は、汎整数拡張をググってみてほしい。


参考リンク
  1. 汎整数拡張 (Wikipedia)
    http://ja.wikipedia.org/wiki/%E6%B1%8E%E6%95%B4%E6%95%B0%E6%8B%A1%E5%BC%B5
プロフィール

島敏博

Shima Toshihiro 島敏博
信州アルプスハイランド在住。HaskellとElixirが好き。組み込みソフトウェアアーキテクト、C++プログラマ、山歩き、美術館巡り、和食食べ歩き、日本赤十字社救急法指導員、インデックス投資、クラシック音楽、SESSAME会員、状態マシン設計、モデル駆動開発、ソフトウェアプロダクトライン、Rubyist、実践ビジネス英語

■ ツイッター
http://twitter.com/saltheads
■ Facebook
http://www.facebook.com/saltheads
■ Qiita
http://qiita.com/saltheads

印刷する場合は、ブラウザの印刷メニューではなく、このページの上から3cmくらいの青いところにある、「印刷」を押してみてください。少しうまく印刷できます。まだ完全ではないのですが、これで勘弁してください。


カテゴリ
最新記事
月別アーカイブ
最新コメント
検索フォーム
リンク
sessame
RSSリンクの表示