6

私は小さなサンプル関数を持っています:

#define VALUE 0

int test(unsigned char x) {
  if (x>=VALUE)
    return 0;
  else
    return 1;
}

私のコンパイラは、比較(x> = VALUE)がすべての場合に真であると警告します。これは、xが符号なし文字であり、VALUEが値0で定義されているためです。そこで、コードを次のように変更しました。

if ( ((signed int) x ) >= ((signed int) VALUE ))

しかし、警告が再び来ます。3つのGCCバージョンでテストしました(すべてのバージョン> 4.0、場合によっては-Wextraを有効にする必要があります)。

変更されたケースでは、この明示的なキャストがあり、signedint比較である必要があります。比較が常に真実であると主張するのはなぜですか?

4

4 に答える 4

12

キャストを使用しても、定義された動作のすべてのケースで比較は依然として当てはまります。コンパイラ(signed int)0は の値が 0 であると判断し(signed int)x)、プログラムで動作が定義されている場合は が非負であると判断します (値が符号付き型の範囲外である場合、符号なしから符号付きへのキャストは未定義です)。

そのため、else ケースを完全に排除し続けるため、コンパイラは警告を続けます。

編集:警告を黙らせるには、コードを次のように記述します

#define VALUE 0

int test(unsigned char x) {
#if VALUE==0
  return 1;
#else
  return x>=VALUE;
#endif
}
于 2009-09-01T13:19:45.323 に答える
7

xは an です。unsigned charこれは 0 から 256 の間であることを意味します。この値は常に >= 0 なので、常に true です。intcharunsigned charsigned intcharif

于 2009-09-01T13:21:13.887 に答える
3

an のすべての値は でunsigned char完全に適用できるintため、キャストを使用しても負の値になることはありません。必要なキャストはsigned char- ただし、その場合は関数シグネチャのxように宣言する必要があります。signed実際には署名付きの値が必要なのに、署名なしの値が必要だとクライアントに嘘をついても意味がありません。

于 2009-09-01T13:22:31.730 に答える
1

#defineof VALUEtoは、関数が次の0ように縮小されることを意味します。

int test(unsigned char x) {
  if (x>=0)
    return 0;
  else
    return 1;
}

xは常にとして渡されるため、ステートメントでキャストするか、にキャストするかに関係なく、unsigned char常にとの間に値が0あります。したがって、コンパイラは、常に以上になること、および句に到達できないことを警告します。255x0signed intifx0else

于 2009-09-01T13:19:24.607 に答える