8

これは簡単な質問ですが、混乱しています。私はかなり典型的なgcc警告を持っていますが、これは通常簡単に修正できます。
warning: comparison between signed and unsigned integer expressions

0x80000000Lのように、最上位ビットの16進定数がある場合は常に、コンパイラーはそれを符号なしとして解釈します。たとえば、このコードを-Wextraでコンパイルすると、警告(gcc 4.4x、4.5x)が発生します。

int main()
{
long test = 1;
long *p = &test;
if(*p != 0x80000000L) printf("test");
}

私は特に定数に接尾辞を付けているのに、なぜこれが起こっているのですか?

4

5 に答える 5

12

Cの符号なし16進定数に対する答えは?関連しています。接尾辞が付いた16進定数にLは、その値を保持できる次のタイプの最初のものがあります。

long
unsigned long
long long
unsigned long long

詳細については、C99ドラフトのセクション[6.4.4.1]を参照してください。

プラットフォームでlongは、おそらく32ビットであるため、(正の)定数を保持するのに十分な大きさではありません0x80000000。したがって、定数unsigned longのタイプは、リストの次のタイプであり、値を保持するのに十分です。

64ビットのプラットフォームでlongは、定数のタイプはlongです。

于 2011-07-18T05:26:19.027 に答える
1

コンパイラは32ビットlong(およびおそらく32ビットintも)を使用0x80000000し、32ビットの符号付き整数には収まらないため、コンパイラはそれを符号なしとして解釈します。これを回避する方法は、何をしようとしているかによって異なります。

于 2011-07-18T06:30:23.763 に答える
0

cによると、標準の16進定数は符号なしです。

于 2011-07-18T05:26:03.143 に答える
0

それは長い間署名されていません。コンパイラは、そのような16進リテラルが署名されていないことが最も望ましいと判断したと思います。キャストしてみてください(unsigned long)0x80000000L

于 2011-07-18T05:27:13.483 に答える
0

C /C++の16進定数は常に符号なしです。ただし、明示的な型キャストを使用して警告を抑制することができます。

于 2011-07-18T05:28:27.330 に答える