Mam kod, który używa porównania 64-bitowych liczb całkowitych. To wygląda podobnie do następującego:-Wyśladowanie porównywania znaków w g ++
#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;
}
Gdy ten kod jest kompilowany w g ++ (próbowałem różnych wersji Ubuntu 12.04 x64: 4.6.3, 4.6.4, 4.7.3, 4.8.0) z flagami -Wall -pedantic -std = C++ 0x test.cpp -o Test dostaję -Wsign-porównać ostrzeżenie dla drugiej linii pierwszego if (wyjście z g ++ - 4.8):
test.cpp:13:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| result < 0xFFF0000000000000LL)
^
a gdy program testowy jest uruchamiany Dostaję dwa wiersze tekstu:
Something is wrong.
Additional check went fine.
Podczas kompilacji samego kodu w systemie Windows przy użyciu MS Visual Studio 11 Express, aktualizacji 2 z domyślnych opcjach projektu dla obu architekturze x64 lub x86 nie dostanę ani ostrzeżenia, ani to wyjście, a nie wyjście jest:
Everything is fine.
Czy to problem w kodzie? Jeśli tak, czy mógłbyś to wskazać? Czy jest to problem z używanym kompilatorem?
Dodanie dodatkowego typu rzutowania dla drugiej stałej w pierwszej instrukcji if usuwa ostrzeżenie w g ++.
To ładne pierwsze pytanie, w tym pełny przykład i wszystkie istotne informacje. –
'0xFFF0000000000000', jako wartość dodatnia, nie pasuje długo. Jednak pasuje on do unsigned long long, więc jest to typ gcc. –
Sufiks 'LL' może być użyty do wymuszenia na kompilatorze wybrania dłuższego typu (' 'LL' jest długi), ale nie do wybrania mniejszego typu, który ma być rzutowany ('(long long) 0xFFF0000000000000' (mówiąc ściśle, jest to implementacja zdefiniowana)). –