プロが教えるわが家の防犯対策術!

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)
}

A 回答 (4件)

C90では、longの表現範囲を超える10進整数定数はunsigned long型になります。


したがって、

if(test == 4294716272){

の部分は、testが通常の算術型変換によってunsigned longに変換され、符号無し整数として比較が行われます。
それに対して、C99では、longの表現範囲を超える10進整数定数はlong long型になります。
したがって、上記の箇所では、testはlong long型に変換され、符号付き整数として評価されます。

参考URL:http://www.kijineko.co.jp/tech/creintro/size-of- …
    • good
    • 0
この回答へのお礼

test == 4294716272 で算術型変換されるのを忘れてました。。。

納得いきました。
ありがとうございます。

お礼日時:2010/02/08 18:45

ついでに:


gcc-4.4.3 では,
gcc -o hoge hoge.c
とこのまま C90 でコンパイルすると
this decimal constant is unsigned only in ISO C90
と警告を出してくれます.
    • good
    • 0

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) には入りません.
    • good
    • 0
この回答へのお礼

詳しい説明ありがとうございます。

お礼日時:2010/02/08 18:46

> unsigned intの計算なのでラップアラウンドが生じtest=4294716272となるのは私の期待どおりです。


計算はunsigned intでもtestがlong型なので、longにキャストされて代入されているでしょう。

動作の違いは
> if(test == 4294716272){
のlong型とunsigned int型の比較が、unsigned long型で行われるかlong long型で行われるかの違いでは?
    • good
    • 0
この回答へのお礼

その通りですね。
ありがとうございました。

お礼日時:2010/02/08 18:45

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!