2016-04-28 6 views
7

Während die Kommentare für this question lesen, stieß ich auf einen Link zum comp.lang.c FAQ, die eine „vorsichtige Zugabe Funktion“ zeigt, die vorgeblich Integer-Überlauf erfasst:Funktioniert diese Funktion zum Erkennen eines ganzzahligen Additionsüberlaufs tatsächlich?

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

Wie funktioniert diese nicht überläuft, wenn b == -1? Wenn die Annahme ist, dass a und b beide positiv sind, warum sie int anstelle von unsigned int an erster Stelle machen?

+2

weil 'INT_MAX - (-1)' gleich 'INT_MIN' ist? – ddz

+2

Signed "int" ** könnte ** wickeln: aber es ist * undefined Verhalten *. –

+1

Nimmt an, dass 'a' und' b' positiv sind. Nützlich für das Konvertieren von Zeichenfolgen in "int", während auf Überlauf geprüft wird. – user3386109

Antwort

1

Wahrscheinlich haben sie es einfach übersehen. Additional links auf der FAQ-Seite scheinen mehr richtigen Code zu bieten.

+1

Und das wird scheitern, wenn 'b == INT_MIN', aber zumindest erwähnen sie es. Ich schätze, es ist wirklich nicht so einfach wie sie vorgeben, was auch meine Erfahrung ist ... – zennehoy

+0

Das sagen sie auch im "richtigen Code": (Anmerkung: Diese Funktionen haben alle einen Fehler: Sie können fehlschlagen, wenn sie auf dem Server aufgerufen werden größte negative Ganzzahl, INT_MIN.). – user3078414

4

OP hat festgestellt, dass INT_MAX - b möglicherweise überläuft, wodurch der verbleibende Code für eine ordnungsgemäße Überlauferkennung ungültig wird. Es funktioniert nicht.

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

Verfahren ohne Überlauf UB erkennen folgt:

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

warum sie int machen anstatt unsigned int in erster Linie?

zu unsigned Ändern löst nicht das Problem im Allgemeinen. Der Bereich von unsigned: [0...UINT_MAX] könnte die Hälfte von int: [INT_MIN...INT_MAX] sein. IOWs: INT_MAX == UINT_MAX. Solche Systeme sind heutzutage selten. IAC, Typen ändern ist nicht erforderlich, wie mit is_undefined_add1() codiert.