2010-09-09 13 views
26

Modificato per includere il riferimento standard corretto grazie a Carl Norum.Overflow intero in C: standard e compilatori

stati standard

Il C

Se un condizioni eccezionali si verifica durante la valutazione di un'espressione (cioè, se il risultato non è matematicamente definito o meno nell'intervallo di valori rappresentabili per il suo tipo), il comportamento non è definito.

Esistono switch del compilatore che garantiscono determinati comportamenti sull'intero overflow? Mi piacerebbe evitare i demoni nasali. In particolare, mi piacerebbe imporre al compilatore di avvolgere in overflow.

Per motivi di unicità, prendiamo lo standard per essere C99 e il compilatore per essere gcc. Ma sarei interessato alle risposte per altri compilatori (icc, cl) e altri standard (C1x, C89). Infatti, solo per infastidire il pubblico di C/C++, apprezzerei anche le risposte per C++ 0x, C++ 03 e C++ 98.

Nota: lo standard internazionale ISO/IEC 10967-1 può essere rilevante qui, ma per quanto posso dire è stato menzionato solo nell'allegato informativo.

risposta

19

Date un'occhiata a -ftrapv and -fwrapv:

-ftrapv

Questa opzione genera trappole per troppo pieno firmato sulle operazioni addizione, sottrazione, moltiplicazione.

-fwrapv

Questa opzione istruisce il compilatore supporre che overflow aritmetico firmato di addizione, sottrazione e moltiplicazione avvolge utilizzando rappresentazione complemento a due. Questo flag abilita alcune ottimizzazioni e disabilita altre. Questa opzione è abilitata per impostazione predefinita per il front-end Java, come richiesto dalle specifiche del linguaggio Java.

+1

Eccellente, proprio quello che volevo vedere. C'è qualcosa di simile per i tipi non firmati? – Charles

+0

@Charles non ne hai bisogno per i tipi senza segno - il comportamento di overflow è già ben definito per loro (vedi la mia risposta). –

+0

@Carl Norum: vedo che è definito in C++ e che è definito in C per i turni (6.5.7 para 5). Non riesco a vedere dove è definito nello standard C per l'addizione e la moltiplicazione. – Charles

0

Non sono sicuro se ci sono degli switch del compilatore che è possibile utilizzare per applicare un comportamento uniforme per gli overflow in C/C++. Un'altra opzione è utilizzare il modello SafeInt<T>. È un modello C++ multipiattaforma che fornisce controlli definitivi di overflow/underflow per tutti i tipi di operazioni con interi.

13

Per la vostra risposta C99, penso 6.5 Espressioni, comma 5 è quello che stai cercando:

Se un condizioni eccezionali si verifica durante la valutazione di un'espressione (cioè, se il risultato non è definito matematicamente o no nell'intervallo di valori rappresentabili per il suo tipo), il comportamento non è definito.

Ciò significa che se si ottiene un overflow, si è fuori di fortuna - nessun comportamento di alcun tipo garantito. tipi senza segno sono un caso speciale, e mai troppopieno (6.2.5 Tipi, punto 9):

Un calcolo coinvolge operandi unsigned può mai troppopieno, perché un risultato che non può essere rappresentato dal tipo intero senza segno risultante è ridotto modulo il numero che è maggiore del valore più grande che può essere rappresentato dal tipo risultante.

C++ ha le stesse dichiarazioni, formulata in modo leggermente diverso:

  • 5 Espressioni, paragrafo 4:

    Se durante la valutazione di un'espressione, il risultato non è matematicamente definito o meno nell'intervallo di valori rappresentabili per il suo tipo, il comportamento non è definito. [Nota: la maggior parte delle implementazioni esistenti di C++ ignora gli overflow integer. Trattamento della divisione per zero, formando un resto usando un divisore nullo, e tutte le eccezioni in virgola mobile variano tra le macchine, e di solito è regolabile tramite una funzione di libreria. -endnote]

  • 3.9.1 tipi fondamentali, comma 4:

    interi senza segno, dichiarato unsigned, deve obbedire alle leggi del modulo aritmetica 2^n dove n è il numero di bit nella rappresentazione del valore di quella particolare dimensione del numero intero.

+0

Sì, questo è quello che stavo cercando. (Anche se il riferimento mi ha confuso all'inizio - questo è il 6.5 paragrafo 5, non la sezione 6.5.5.) Sai qualche modo per evitarlo? Il wrapping su overflow è comune, e ci sono molte volte in cui voglio che questo accada. Qualche compilatore popolare ha un interruttore che le fa promettere di avvolgere? – Charles

+0

@Charles, il comportamento non definito non è definito. Potresti essere fortunato con il tuo particolare compilatore - controlla la sua documentazione per una dichiarazione che ti dia tranquillità. Ad esempio, in 'gcc' puoi controllare i flag' -fstrict-overflow' e '-fwrapv'. –

7

In C99 il comportamento generale desribed in 6,5/5

Se un condizioni eccezionali verifica durante la valutazione di un'espressione (cioè, se il risultato non è matematicamente definito o non nell'intervallo di valori rappresentabili per il suo tipo ), il comportamento non è definito.

Il comportamento dei tipi senza segno è descritto in 6.2.5/9, in cui si afferma che fondamentalmente operazioni su tipi senza segno non portano a condizioni eccezionali

Un calcolo coinvolge firmati operandi può mai troppopieno, perché di conseguenza che non può essere rappresentato da tipo intero senza segno risultante è ridotta modulo il numero che è uno maggiore del valore più grande può essere rappresentata dalla tipo risultante.

Il compilatore GCC ha un'opzione speciale -ftrapv, che è destinata a rilevare l'overflow di esecuzione delle operazioni con numero intero con segno.

2

6.2.5 comma 9 è quello che stai cercando:

L'intervallo di valori non negativi di tipo intero con segno è un sottoinsieme del corrispondente senza segno tipo intero, e la rappresentazione della lo stesso valore in ogni tipo di è uguale.31) Un calcolo che coinvolge operandi senza segno non può mai traboccare, perché un risultato che non può essere rappresentato dal tipo di intero senza segno risultante è modulo ridotto il numero che è maggiore del valore maggiore che può essere rappresentato dal resul tipo di

Problemi correlati