#include <stdio.h>
int main(void)
{
printf("%d", sizeof(signed int) > -1);
return 0;
}
結果は0(FALSE)です。どうすればいいですか?私は64ビットのubuntulinuxを使用しているので、結果は(4> -1)=> 1=>Trueになります。
これは、sizeof
演算子が符号なしの数量(size_t
)を返すことです。したがって、比較は-1
unsignedに昇格し、非常に大きな数のように見えます。
あなたが試すことができます:
printf("%d", ((int)sizeof(signed int)) > -1);
sizeof(signed int)
size_t
符号なしタイプであるタイプがあります。符号付きの値と符号なしの値を比較すると[符号なしの値のタイプは少なくとも符号付きの値のタイプと同じ大きさです]、比較の前に符号付きの値が符号なしに変換されます。この変換により、符号なし型の可能な最大-1
値になります。言い換えれば、それはあなたが書いたかのようです
#include <limits.h>
/* ... */
printf("%d", sizeof(signed int) > SIZE_MAX);
この間違いをしたときにgccに警告を出すことができますが、デフォルトではオンになっておらず、さらに具体的には-Wall
次のようになっています。(この警告は非常に多くの誤検知を引き起こす可能性がありますが、新しいコードをオンにすると便利だと思います。)-Wextra
-Wsign-compare
Cには多くの暗黙の変換があり、整数プロモーションと呼ばれるものを含む「通常の算術変換」と呼ばれるものを理解することは特に役立ちます。1
実際のルールは少し複雑ですが、単純化すると、演算子に異なるタイプのオペランドがある場合、すべてのスカラータイプが自動的に変換されます。変換は、最初に下位ランクのオペランドを取得し、それを上位ランクのタイプに変換します。次に、1つのオペランドのみが符号付きの場合、符号付きタイプのオペランドが大きく、符号なしタイプのすべての値を表すことができなければ、符号なしに変換されます。size_tはほとんどの場合、intと同じかそれよりも大きいため、この例ではそうではありません。
最後に、ほとんどすべてのマシンで、-1にはすべてのビットが設定されているため、符号なしと見なすと非常に大きな数値になります。
1. ISO / IEC 9899:1999 ( "C99") 6.3変換