2011-09-22 9 views
8

Mam następujący kod:Dziwne zachowanie ostrzeżenie z gcc i podpisane/niepodpisane porównania

unsigned int a; 
if (a > numeric_limits<int>::max()) 
    do_stuff(); 

Podczas kompilacji gcc narzeka na

ostrzeżenie: "porównania między podpisane i niepodpisane"

OK, rozumiem

Ale z następującym kodem:

unsigned int a; 
if (a > (numeric_limits<int>::max())) 
    do_stuff(); 

Ostrzeżenie nie jest już wyświetlany, a ja naprawdę nie wiem, dlaczego ... Czy istnieje jakiś logiczny powód takiego zachowania albo robię coś źle ?!

+1

Próbował [symulować to zachowanie] (http: // www. ideone.com/5NZL9). Ale pokazuje ostrzeżenie. – iammilind

+0

Jaki jest otaczający kod? – quasiverse

+0

Część do_stuff() polega tylko na rzucaniu wyjątku. Nie ma kodu otaczającego, ponieważ jest to jedyne linie w funkcji. Jednak funkcja jest używana w dużym projekcie. Próbowałem kod dostarczony przez iammilind, ale ostrzeżenie nie pojawia się. Oto opcje gcc, których używam do kompilowania programu '-Wall -ansi -pedantic -Wno-long-long'' – malamioute

Odpowiedz

-1

Odpowiedź leży w sposobie, w jaki gcc obsługuje int i unsigned int.

i int oba przechowują wartość 2-bajtową. Różnica między nimi polega na tym, że unsigned int nie obsługuje wartości ujemnych. Może przechowywać tylko wartości od 0-65,535. Gdy GCC widzi porównanie int i unsigned int, konwertuje int na liczbę dodatnią. np. jeśli wartość int wynosi -2, zmieni ją na 2. Ale jeśli int jest poprzedzone operatorem(). (int). GCC interpretuje ją jako liczbę dodatnią (ale nadal ją konwertuje) i nie daje ostrzeżenia.

+0

'int' nie jest ogólnie wartością" 2-bajtową ", a nie na prawie każdym kompilatorze C++ aktualnie używanym. –

0

nie mają obecnie dostępu do C++ do sprawdzenia tego, ale myślę, że to może działać bez żadnych ostrzeżeń:

unsigned int a; 
if (a > numeric_limits<unsigned int>::max()) 
    do_stuff(); 
+0

To powinno definitywnie wygenerować ostrzeżenie (oświadczenie zawsze jest fałszywe)! – UncleBens

+0

Aby uzyskać ten sam wynik bez ostrzeżenia, należy użyć 'if (a> unsigned (numeric_limits :: max()))'. – UncleBens

+0

Ja też to widzę. 'a' nie może być większe niż' 0xffffffff', więc 'if (a> unsigned (numeric_limits :: max()))' jest poprawne, jak wskazano @UncleBens. – npclaudiu