2011-09-22 13 views
8

Ho il seguente codice:comportamento avvertimento Strano con gcc e firmate/i confronti non firmati

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

Quando si compila, gcc si lamenta

avvertimento: "confronto tra firmato e unsigned"

OK, ho capito

Ma, con il seguente codice:

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

L'avvertimento non viene più visualizzato e io davvero non so perché ... v'è alcuna ragione logica per un tale comportamento o sto facendo qualcosa di sbagliato ?!

+1

Cercato di [simulare questo comportamento] (http: // www. ideone.com/5NZL9). Ma mostra un avvertimento. – iammilind

+0

Qual è il codice circostante? – quasiverse

+0

La parte do_stuff() consiste solo nel generare un'eccezione. Non esiste un codice circostante in quanto questa è l'unica linea all'interno di una funzione. Tuttavia, la funzione è utilizzata in un grande progetto. Ho provato il codice fornito da iammilind ma l'avviso non compare. Ecco le opzioni di gcc che uso per compilare il programma '-Wall -ansi -pedantic -Wno-long-long' – malamioute

risposta

-1

La risposta sta nel modo in cui gcc gestisce int e unsigned int.

unsigned int e int memorizzano entrambi un valore di 2 byte. La differenza tra loro è che unsigned int non supporta valori negativi. Può solo memorizzare valori da 0 a 65.535. Quando GCC vede un confronto tra int e unsigned int converte l'int in un numero positivo. ad esempio, se il valore di int è -2, verrà convertito in 2. Ma se l'int è preceduto dall'operatore(). (Int). GCC lo interpreta come un numero positivo (ma lo converte ancora) e non fornisce un avvertimento.

+0

'int' non è un" valore di 2 byte "in generale, e non su praticamente nessun compilatore C++ attualmente utilizzato. –

0

Io attualmente non hanno accesso a un compilatore C++ di testare questo, ma penso che questo potrebbe funzionare senza avvisi:

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

Questo dovrebbe sicuramente produrre un avvertimento (dichiarazione sempre falsa)! – UncleBens

+0

Per ottenere lo stesso risultato senza un avvertimento, prenderebbe if (a> unsigned (numeric_limits :: max())) '. – UncleBens

+0

Lo vedo anche io. 'a' non può essere maggiore di' 0xffffffff', quindi 'if (a> unsigned (numeric_limits :: max()))' è corretto, come indicato @UncleBens. – npclaudiu