- ベストアンサー
C90とC99の計算結果の違い?
C言語の質問です。 gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu12) 以下のプログラムをgccでコンパイル・実行すると(1)に入り,"a"が出力されます。unsigned intの計算なのでラップアラウンドが生じtest=4294716272となるのは私の期待どおりです。 ただ、gcc -std=c99でコンパイル・実行すると(2)に入り,"b"が出力されました。c99でコンパイル・実行すると計算結果がなぜ異なっているのかが分かりません。 long test = 0; unsigned int x = 184; unsigned int y = 251208; test = (x-y); if(test == 4294716272){ printf("a");// (1) }else if(test == -251024){ printf("b"); // (2) }
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
C90では、longの表現範囲を超える10進整数定数はunsigned long型になります。 したがって、 if(test == 4294716272){ の部分は、testが通常の算術型変換によってunsigned longに変換され、符号無し整数として比較が行われます。 それに対して、C99では、longの表現範囲を超える10進整数定数はlong long型になります。 したがって、上記の箇所では、testはlong long型に変換され、符号付き整数として評価されます。
その他の回答 (3)
- Tacosan
- ベストアンサー率23% (3656/15482)
ついでに: gcc-4.4.3 では, gcc -o hoge hoge.c とこのまま C90 でコンパイルすると this decimal constant is unsigned only in ISO C90 と警告を出してくれます.
- Tacosan
- ベストアンサー率23% (3656/15482)
C90 と C99 では, 「10進整定数の型」の決め方が異なります. いずれも「その値を表すことのできる最も小さな型」でますが, C90 では int → long → unsigned long の順に調べるのに対し C99 では int → long → long long の順に調べます. 今の場合 4294716272 は int でも long でも表現できないため, C90 では unsigned long として, C99 では long long として扱います. 従って C90 の環境では test を unsigned long に変換するので (1) に入りますが, C99 の環境では test を long long に変換するので (1) には入りません.
お礼
詳しい説明ありがとうございます。
- rinkun
- ベストアンサー率44% (706/1571)
> unsigned intの計算なのでラップアラウンドが生じtest=4294716272となるのは私の期待どおりです。 計算はunsigned intでもtestがlong型なので、longにキャストされて代入されているでしょう。 動作の違いは > if(test == 4294716272){ のlong型とunsigned int型の比較が、unsigned long型で行われるかlong long型で行われるかの違いでは?
お礼
その通りですね。 ありがとうございました。
お礼
test == 4294716272 で算術型変換されるのを忘れてました。。。 納得いきました。 ありがとうございます。