2013-08-06 12 views
7

Sto usando il compilatore RVCT per compilare il codice in C (sezione pertinente qui):Attenzione - Intero risultato dell'operazione è fuori campo in c

static void Test (void) 
{ 
    unsigned long regVal; 
    regVal |= (UINT32)( (0x1 << 31)  | 
          (0x1 << 26)  | 
          0x3E); 
} 

Quando si compila il codice, viene visualizzato il seguente avviso Attenzione : "# 61-D: il risultato dell'operazione integer è fuori intervallo".

Mi piacerebbe capire cosa cambiare per evitare l'avviso.

Grazie in anticipo!

+2

Si consiglia di inizializzare 'regVal' o di assegnarlo solo con l'operatore' = 'anziché con l'operatore' | = '. – patrickvacek

+1

@patrickvacek mentre quello è certamente un punto valido, non penso che questo sia il punto principale di questa domanda. –

+0

Non ho familiarità con quel compilatore, ma di solito, quella variabile assumerà un valore casuale, NON verrà inizializzata a 0. Cambia il tuo | = a = per evitare. – oyvind

risposta

7

A causa delle regole di promozione intera, l'espressione interna (vale a dire prima della trasmissione (UINT32)) viene considerata come signed int. Pertanto, 0x1 << 31 è 0x80000000, che è un numero intero con segno negativo, pertanto risulta l'avviso. Per risolvere il problema, puoi forzare i turni a non firmare aggiungendo "U" alle costanti esadecimali, come 0x1U.

regVal |= (UINT32)( (0x1U << 31)  | 
         (0x1U << 26)  | 
         0x3EU); 

Questo costringerà tutti i turni e bit per bit OR per essere firmato, che dovrebbe sbarazzarsi del warning (e rimuove anche la necessità di (UINT32) cast, dal momento che è già non firmato).

+0

Grazie. L'aggiunta di U ha risolto questo problema –

2

L'avviso di overflow del compilatore è corretto, perché l'espressione 1 < < 31 rappresenta un int firmato. Per evitare l'avviso, definire esplicitamente la costante 0x1 come valore senza segno usando U postfix. Ad esempio:

unsigned long regVal; 
regVal |= (UINT32)( (0x1U << 31)  | 
         (0x1 << 26)  | 
         0x3E); 
Problemi correlati