6

gcc 4.4.5-Wtype-limitsオプションをオンにして小さなコード スニペットをテストしています。

#include <assert.h>
#include <limits.h>
#include <stdint.h>

int main(void)
{
    /* With other values of v, the behavior of the compiler is the same. */
    uint16_t v = 0; 
    assert((unsigned int)INT_MAX < (unsigned int)v); /* l. 7 */
    return 0;
}

次に、コンパイラは次の警告をスローします。

main.c:7: warning: comparison is always false due to limited range of data type

ただし、私の知る限り、( C11 (n1570) から、§ 5.2.4.2.1 整数型のサイズ)INT_MAXと等しい可能性があります。その場合、変数は値を保持でき、 の式は に評価されます。+32767<limits.h>vINT_MAX+1assert1

したがって、次の 2 つの問題があります。

  • GCC は私のアーキテクチャを考慮に入れています。実際にINT_MAXは と等しくないから+32767です。その場合、-Wtype-limits私にとってのメリットが減少します。
  • バグです。

2 番目のオプションについて考えさせられるのは、同じオプションで警告を生成しない次のコードです。

#include <assert.h>
#include <limits.h>
#include <stdint.h>

int main(void)
{
    assert((unsigned int)INT_MAX < (unsigned int)UINT16_MAX);
    return 0;
}

それで、正しい答えは何ですか?

PS:ところで、gccのバージョンが古いため、申し訳ありません。おそらく、次のリリースの動作は異なるでしょう。

4

1 に答える 1

5

GCC は、型の実際の既知の制限を考慮に入れます。intあなたのケースでは幅が16ビットを超えていることがわかっているので、警告します。

警告は表示されません

#include <assert.h>
#include <limits.h>
#include <stdint.h>

int main(void)
{
    assert((unsigned int)INT_MAX < (unsigned int)UINT16_MAX);
    return 0;
}

標準は 7.20.2 (2) で次のように述べているためです。

#if定義されたマクロの各インスタンスは、前処理ディレクティブでの使用に適した定数式に置き換えられます。この式は、整数昇格に従って変換された対応する型のオブジェクトである式と同じ型を持つ必要があります。

したがって、32 ビット幅intの s では、マクロUINT16_MAXは ですint。したがって、関連する型の制限によって、比較が常に false (または true) になることが保証されません。

于 2013-04-24T19:11:26.567 に答える