2016-04-28 5 views
7

Durante la lettura dei commenti per this question, mi sono imbattuto in un link al comp.lang.c FAQ che mostra una "funzione aggiunta attenta" che rileva presumibilmente integer overflow:Questa funzione per rilevare l'overflow di aggiunta di interi funziona effettivamente?

int 
chkadd(int a, int b) 
{ 
    if (INT_MAX - b < a) { 
     fputs("int overflow\n", stderr); 
     return INT_MAX; 
    } 
    return a + b; 
} 

Come fa questo non overflow se b == -1? Se l'assunto è che a e sono entrambi positivi, perché renderli int anziché unsigned int in primo luogo?

+2

perché 'INT_MAX - (-1)' è uguale a 'INT_MIN'? – ddz

+2

Firmato 'int' ** potrebbe ** wrap: ma è * comportamento non definito *. –

+1

Presuppone che 'a' e' b' sono positivi. Utile per convertire stringhe in 'int' mentre si controlla l'overflow. – user3386109

risposta

1

Probabilmente l'hanno semplicemente trascurato. Additional links nella pagina delle domande frequenti sembra fornire un codice più corretto.

+1

E quelli non funzioneranno se 'b == INT_MIN', ma almeno lo menzionano. Immagino che non sia così facile come fingono, che è anche la mia esperienza ... – zennehoy

+0

Questo è quello che dicono anche nel "codice corretto": (Nota: queste funzioni condividono un solo bug: possono fallire se invocate sul il più grande numero intero negativo, INT_MIN.). – user3078414

4

L'OP ha identificato che INT_MAX - b può traboccare, rendendo il codice rimanente non valido per il rilevamento di overflow corretto. Non funziona.

if (INT_MAX - b < a) { // Invalid overflow detection 

Un metodo per rilevare troppo pieno, senza UB segue:

int is_undefined_add1(int a, int b) { 
    return (a < 0) ? (b < INT_MIN - a) : (b > INT_MAX - a); 
} 

perché li rendono int piuttosto che unsigned int in primo luogo?

Passaggio a unsigned non risolve il problema in generale. L'intervallo di unsigned: [0...UINT_MAX] potrebbe essere la metà di quello di int: [INT_MIN...INT_MAX]. IOW: INT_MAX == UINT_MAX. Tali sistemi sono rari in questi giorni. IAC, i tipi di modifica non sono necessari come codificati con is_undefined_add1().

Problemi correlati