2010-03-08 11 views
10

Gibt es eine allgemeine Möglichkeit, nach einem Überlauf oder einem Unterlauf eines bestimmten Datentyps (uint32, int usw.) zu suchen?Auf Unterlauf/Überlauf in C++ prüfen?

ich so etwas wie dies tue:

uint32 a,b,c; 
... //initialize a,b,c 
if(b < c) { 
    a -= (c - b) 
} 

Als ich nach einigen Iterationen zu drucken, zeigt es eine große Zahl wie: 4294963846.

+0

[Erkennen von Ganzzahlüberlauf in C/C++?] (http://stackoverflow.com/q/199333/995714) –

Antwort

9

für Über-/Unterschreitung in der Arithmetik Um zu prüfen, das Ergebnis überprüfen im Vergleich zu den ursprünglichen Werten.

uint32 a,b; 
//assign values 
uint32 result = a + b; 
if (result < a) { 
    //Overflow 
} 

Für Ihre spezifischen würde die Prüfung sein:

if (a > (c-b)) { 
    //Underflow 
} 
+0

Danke. Das scheint jetzt gut zu funktionieren ... – Legend

+0

ist das die Tatsache, dass im Falle eines Überlaufs die Antwort immer eine vorzeichenbehaftete (negative ganze Zahl) sein wird? – Faizan

+0

Der Überlauf von Ganzzahlen ohne Vorzeichen wird niemals signiert, sondern ist eine kleinere Ganzzahl ohne Vorzeichen als die ursprünglichen Werte. –

4

Ich denke, wenn ich wollte, dass ich eine Klasse machen, die den Datentyp simuliert, und tun es manuell (welche langsam sein würde ich könnte mir vorstellen)

class MyInt 
{ 
    int val; 
    MyInt(const int&nval){ val = nval;} // cast from int 
    operator int(){return val;} // cast to int 

    // then just overload ALL the operators... putting your check in 
}; 

//typedef int sint32; 
typedef MyInt sint32; 

es mehr als das kann tückisch sein, könnte man eine Definition anstelle eines typedef aufzuwickeln haben mit ...

Ich habe eine ähnliche Sache mit Zeigern gemacht, um zu überprüfen, wo Speicher außerhalb der Grenzen ausgeschrieben wurde. sehr langsam, aber hat gefunden, wo Speicher wurde korrumpiert

+0

War auf der Suche nach einem einfacheren Ansatz ... Aber in jedem Fall, danke für diese .. – Legend

+0

Es gibt eine Version von diesem [namens SafeInt] (http: //safeint.codeplex .com /) dass ich von heute Abend erfahren habe. Es ist wahrscheinlich keine schlechte Idee, so etwas zu verwenden, nur nicht im leistungskritischen Code. – HostileFork

2

Cert hat eine gute Referenz für beide signed integer overflow, die undefined Verhalten ist und unsigned wrapping die nicht ist und sie alle Betreiber abdecken.

Das Dokument enthält folgende Prüfcodes für unsigned Verpackung in Subtraktion Voraussetzungen ist wie folgt:

void func(unsigned int ui_a, unsigned int ui_b) { 
    unsigned int udiff; 
    if (ui_a < ui_b){ 
    /* Handle error */ 
    } else { 
    udiff = ui_a - ui_b; 
    } 
    /* ... */ 
} 

und mit post-Bedingungen:

void func(unsigned int ui_a, unsigned int ui_b) { 
    unsigned int udiff = ui_a - ui_b; 
    if (udiff > ui_a) { 
    /* Handle error */ 
    } 
    /* ... */ 
} 

Wenn Sie gcc 5 sind, können Sie __builtin_sub_overflow verwenden :

__builtin_sub_overflow(ui_a, ui_b, &udiff)