2016-08-25 1 views
0

Ich habe über ganze Zahl überquellender, untersucht, und ich eine Funktion ended schaffen, die für Integer-Überläufe und Unterschreitungen prüft: Wann muss ich auf Ganzzahlüberlauf prüfen?

#include <exception> 
#include <limits> 

int safe_add(int a, int b) { 
    if (a > 0 && b > INT_MAX - a) { 
     throw std::exception("Integer overflow"); 
    } else if (a < 0 && b < INT_MIN - a) { 
     throw std::exception("Integer underflow"); 
    } 
    return a + b; 
} 

Ich war die möglichen Leistungsprobleme Angst, so habe ich die nächste Benchmark:

#include <iostream> 
#include <exception> 
#include <limits> 
#include <chrono> 
#include <string> 

int safe_add(int a, int b) { 
    if (a > 0 && b > INT_MAX - a) { 
     throw std::exception("Integer overflow"); 
    } else if (a < 0 && b < INT_MIN - a) { 
     throw std::exception("Integer underflow"); 
    } 
    return a + b; 
} 

void bench_add() { 
    for (int i = INT16_MIN; i < INT16_MAX; i++) { 
     for (int j = INT16_MIN; j < INT16_MAX; j++) { 
      volatile int x = i + j; //I make it volatile so the compiler doesn't optimize it out 
     } 
    } 
} 

void bench_safe_add() { 
    for (int i = INT16_MIN; i < INT16_MAX; i++) { 
     for (int j = INT16_MIN; j < INT16_MAX; j++) { 
      volatile int x = safe_add(i, j); //I make it volatile so the compiler doesn't optimize it out 
     } 
    } 
} 

void bench_safe_add_with_try() { 
    try { 
     for (int i = INT16_MIN; i < INT16_MAX; i++) { 
      for (int j = INT16_MIN; j < INT16_MAX; j++) { 
       volatile int x = safe_add(i, j); //I make it volatile so the compiler doesn't optimize it out 
      } 
     } 
    } catch (std::exception& e) { 
     std::cout << e.what() << std::endl; 
    } 
} 

void chrono(const std::string& name, void function(void)) { 
    using namespace std::chrono; 
    milliseconds start = duration_cast<milliseconds>(system_clock::now().time_since_epoch()); 
    function(); 
    long long time = (duration_cast<milliseconds>(system_clock::now().time_since_epoch()) - start).count(); 
    std::cout << name << ": " << time << "ms" << std::endl; 
} 

int main() { 
    chrono("Standard add", bench_add); 
    chrono("Safe add", bench_safe_add); 
    chrono("Safe add surrounded by try block", bench_safe_add_with_try); 
    system("PAUSE"); 
    return 0; 
} 

In meinem Rechner (i7-6700K @ 4GHZ 16gb RAM) erzeugt diese Ausgabe:

Standard add: 1341ms 
Safe add: 13667ms 
Safe add surrounded by try block: 13544ms 

Wenn ich zuerst die Funktion mit dem try-Block anrufe, dann sinkt die sichere Add-Zeit sehr ab. Vielleicht zur Verzweigungsvorhersage?

Der Punkt ist, dass es scheint, dass safe_add ist viel langsamer als einfach hinzufügen, also wann sollte ich für Integer-Überläufe prüfen? oder wann sollte ich NICHT für ganzzahlige Überläufe überprüfen? Ist es wichtig, es bei jeder Benutzereingabe zu verwenden oder sollte das Programm einfach abstürzen? Und wenn Sie Datenbanken führen, bei denen die Auswirkungen auf die Performance viel größer sind, weil sie eine andere Abfrage benötigen?

Vielen Dank, Pedro.

+1

Das Programm nicht auf Integer-Überlauf zum Absturz garantiert. Es hat undefiniertes Verhalten, was bedeutet, dass es alles und nichts tun kann. Wenn Sie sicher sind, dass ein Vorgang nicht überlaufen kann, prüfen Sie nicht, ob ein Überlauf vorliegt. Sie könnten zum Beispiel beschränkte Werte haben. Wenn Sie nicht sicher wissen können, müssen Sie überprüfen. –

+2

@Krythic Sorry, wenn ich falsch das Wort Forschung verwendet habe, bin ich kein englischer Muttersprachler –

+0

@ IljaEverilä Zumindest in VC++ wird eine Ausnahme ausgelöst, wenn es einen ganzzahligen Überlauf gibt. –

Antwort

0

@nikitoz hat die Antwort gegeben Ich wollte:

Sie nie für Integer-Überlauf überprüfen müssen. Validiere Benutzereingaben gegen einige Plausibilitätsprüfungen, benutze long long type, wenn du große Zahlen erwartest, benutze spezielle Klasse für sehr große Ganzzahlen von egal welche Größe du brauchst (normalerweise nicht). Programm wird nicht wegen Integer-Überlauf abstürzen.

So werde ich diese Marke als beantwortet

Verwandte Themen