私は64ビット整数の比較を使用するコードを持っています。それは次のようになります-g ++のWsign-compare警告
#include <cstdio>
long long getResult()
{
return 123456LL;
}
int main()
{
long long result = getResult();
if (result > 0x000FFFFFFFFFFFFFLL
|| result < 0xFFF0000000000000LL)
{
printf("Something is wrong.\n");
if (result > 0x000FFFFFFFFFFFFFLL
|| result < -4503599627370496LL)
{
printf("Additional check failed too.\n");
}
else
{
printf("Additional check went fine.\n");
}
}
else
{
printf("Everything is fine.\n");
}
return 0;
}
このコードはGでコンパイルされると++(Ubuntuの12.04 x64で異なるバージョンを試してみました:4.6.3、4.6.4、4.7.3、4.8.0)のフラグを-Wall -pedantic -std = C++ 0xのTEST.CPP -oテスト私は-Wsign-比較すると、最初のステートメント(G ++からの出力 - 4.8)の2行目のための警告を得る:
test.cpp:13:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| result < 0xFFF0000000000000LL)
^
そして、テストプログラム私は2行のテキストを得る:
Something is wrong.
Additional check went fine.
x86またはx64アーキテクチャのいずれかのデフォルトのプロジェクトオプションでMSのVisual Studio 11 Expressのアップデート2を使用してWindows上で同じコードをコンパイルするとき、私は警告も、この出力どちらを得ることはありません、代わりに出力されている:
Everything is fine.
されていますそれはコードの問題ですか?はいの場合は、それを指摘できますか?それとも、コンパイラに問題がありますか?
最初のifステートメントで2番目の定数の型キャストを追加すると、g ++で警告が削除されます。標準で[lex.icon]によれば、16進リテラル0xFFF0000000000000LL
値がlong long
に収まらないので、unsigned long long
型を持つ
これは素晴らしい例です。完全な例と関連するすべての情報が含まれています。 –
「0xFFF0000000000000」は正の値としてlong longに収まりません。しかし、それはunsigned long longに収まるので、gccが使用する型です。 –
拡張子 'LL'はコンパイラに長い型(' 1LL'はlong long)を選択させますが、より小さい型は選択しないようにするために使用できます。 '(long long)0xFFF0000000000000'(厳密に言えば、これは定義された実装です))。 –