2010-02-28 12 views
12

Ho array seguente, che ho bisogno di operare a mano su bitmap.C++: avviso del compilatore per int unsnigned grande

const unsigned int BITS[32] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 
           2048, 4096, 8192, 16384, 32768, 65536, 131072, 
           262144, 524288, 1048576, 2097152, 4194304, 
           8388608, 16777216, 33554432, 67108864, 134217728, 
           268435456, 536870912, 1073741824, 2147483648}; 

Purtroppo, quando compilato ottengo

avvertimento: questa costante decimale è senza segno solo in ISO C90

Come posso rimuovere questo?

+0

Vai a questa domanda simile: http://stackoverflow.com/questions/2347936/cant-get-ride-of-this-decimal-constant -is-unsigned-only-in-iso-c90-warning –

+0

Perché stai facendo questo? Se pensi che una tabella di ricerca sarà più veloce del semplice calcolo di questi valori secondo necessità, ripensaci ... – Nemo

risposta

15

I valori letterali interi in C sono, di default, di tipo "signed int" (edit: ma vedere i commenti per i caveat). L'ultimo numero è troppo grande per essere rappresentato come un intero a 32 bit con segno, e quindi è necessario dire al compilatore che si tratta di un intero senza segno dal suffisso con "U", come:

2147483648U 

Si noti che puoi anche aggiungere un suffisso di "L" per renderlo un "long", ma su molti sistemi che sono ancora a 32 bit e quindi irrilevanti.

Inoltre, c'è un modo soggetto a errori (e più facile da leggere) molto meno di scrivere questo codice, con l'operatore bit-shift:

const unsigned int BITS[32] = {1U, 1U<<1, 1U<<2, 1U<<3, 1U<<4, 
           /* and so on */ 
           1U<<31}; 

Oppure, scrivere in esadecimale, se don 't come turni di bit per qualche motivo:

const unsigned int BITS[32] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 
           /* and so on */ 
           0x80000000U}; 
+0

Perché il compilatore lo tratta quindi come un int, piuttosto che automaticamente lo trasforma in uint? Soprattutto, che sa esattamente in che tipo verrà memorizzato. – gruszczy

+0

In molti casi non è possibile sapere che tipo è una costante (ad esempio, come argomento di funzione in una funzione varargs), quindi deve essere specificata esplicitamente. È confuso il fatto che il tipo sia implicito alcune volte e che sia necessario specificarlo esplicitamente negli altri, e anche confondendo di avere la stessa costante di tipi diversi su sistemi con diverse dimensioni int. Inoltre, poiché C non scrive mai un tipo di inferenza di questo tipo, aggiungendolo per questo caso si complicherebbe parecchio il parser senza alcun beneficio significativo. –

+3

@gruszczy: In C89/90 una costante decimale non tratteggiata deve essere interpretata come 'int',' long' o 'unsigned long' (a seconda della condizione che si adatta prima). In C99 deve essere interpretato come 'int',' long' o 'long long' (qualsiasi cosa vada per prima). Questo è ciò che il compilatore sta cercando di dire con questo avvertimento. Apparentemente, su questa piattaforma 'long' ha la stessa dimensione di' int'. Il compilatore sta fondamentalmente dicendo: "forse stavi cercando di creare una costante 'firmata lunga' o forse anche una 'lunga lunga' costante, ma con le regole C89/90 devo renderla' unsigned long'. – AnT

6

vostro costante deve essere specificato come unsigned troppo, utilizzare

2147483648UL 

(UL = Unsigned Long), o semplicemente

2147483648U 

per un unsigned int.

Come il tuo codice è adesso, una costante, che per default è un semplice int, e quindi firmata, è assegnata a un unsigned int, che genera il tuo avviso.

+0

Che ha funzionato, grazie mille :-) – gruszczy

+3

Pedandicamente parlando, l'errore non è che dal fatto int) costante è assegnata a un int unsigned; il compito è irrilevante. L'errore è dovuto al fatto che il valore di "2147483648" è troppo grande per essere un int firmato e quindi, in primo luogo, c'è un overflow nella generazione della costante int signed. –

+2

In realtà, il vero motivo dell'avvertimento è che il compilatore deve scegliere "unsigned long" per il tipo costante. (Nota, di nuovo, questa costante non è 'unsigned int', è' unsigned long'.) E deve sceglierla specificatamente in C89/90, invece di scegliere un tipo firmato più grande (che potrebbe supportare) o dopo C99 regole e scelta 'lunga lunga'. Questo è l'avvertimento e perché si riferisce a "ISO C90". Ad esempio, in C99 una costante decimale senza suffisso non verrà mai assegnata a un tipo senza segno. – AnT

1

Non è necessario definire il tipo di dati come tipo appena unsigned;

int variable_name=2147483648U; 

altro solo convertire il valore decimale in esadecimale ...

Problemi correlati