Zahlen addieren



  • Welche Möglichkeiten hat man mit ANSI C, um auf das Overflow Flag zu reagieren ?
    Hier mein Beispielcode:

    #include <stdio.h>
    
    int main(){
    	int a = 0, b = 0, c = 0;
    
    	scanf("%d%d", &a, &b);
    
    	c = a + b;
    
    	__asm{ /* Tut halbwegs, was es soll, aber ist nicht ANSI C */
    		JO overflow
    	}
    
    	printf("Korrekte Summe %d", c);
    	goto progEnde;
    
    overflow:
    	printf("Fehlerhafte Summe (Overflow) %d", c);
    
    progEnde:
    	getchar();
    	getchar();
    	return 0;
    }
    

    Wie leicht zu sehen ist, erscheint mir die einzige Möglichkeit,
    dem Arithmetischen Overflow den Kampf anzusagen, die Verwendung von __asm
    Blöcken zu sein. Leider resultiert daraus auch ziemlich schnell ein erheblicher
    Spaghetticode mit Jumps und Gotos, habe leider keine ANSI-C Funktion gefunden,
    mit der ich auf den Überlauf 'eleganter' reagieren könnte.
    Erschwerend kommt hinzu, dass wenn ich die Variablen a, b, c z.B. als
    short deklariert hätte, dann würden die Zahlen von meinem Compiler trotzdem
    jeweils in EAX und ECX hineingeladen (d.h. vorübergehend zu 32-Bit-Integers
    expandiert werden), und dann wird auch erst gar nicht das Overflow-Flag
    gesetzt, wenn EAX und ECX addiert werden, weil das Resultat von zwei shorts ja
    in jedem Fall in einem 32-Bit Register Platz hat. Wenn dann das Resultat
    allerdings wieder z.B. in short c gespeichert würde, dann käme natürlich
    trotzdem ein fehlerhaftes Additions-Ergebnis heraus, weil ja c nur 16-Bit groß
    ist. Diese Overflow-Erkennung mit JO overflow funktioniert also - wenn überhaupt - nur mit 32-Bit Zahlen.
    Ist es nicht ärgerlich, dass man - trotz topmoderner CPUs - bei jeder
    Berechnung, die man durchführt, statistisch nur ca. eine 50% Chance hat, dass
    das Ergebnis auch stimmt? In den anderen 50% der Fälle sorgt nämlich leider
    ein (mit Hoch-Sprachen-Mitteln schwer zu bekämpfender!) OVERFLOW für ein
    falsches Resultat.
    Wie sinnvoll ist es dann noch, irgendetwas zu programmieren, wenn die Maschine
    nicht mal elementare Additionen richtig ausrechnen kann (bzw. nur zu 50%)?

    Mit welchen Mitteln geht Ihr gegen OVERFLOWs vor? Gibt's da eventuell doch
    das eine oder andere (Hochsprachen-ANSI-C-) Mittel, um sich gegen den OVERFLOW
    erfolgreich zur Wehr zu setzen? 😕



  • bei unsigned int mache ich

    c=a+b;
    if(c<a)//oder if(c<b) oder if(c<a||c<b), alles gleichwertig
    


  • Überläufer schrieb:

    Welche Möglichkeiten hat man mit ANSI C, um auf das Overflow Flag zu reagieren ?

    Überhaupt keine.

    Wie leicht zu sehen ist, erscheint mir die einzige Möglichkeit,
    dem Arithmetischen Overflow den Kampf anzusagen, die Verwendung von __asm
    Blöcken zu sein.

    Wenn du sicherstellen kannst, dass sie direkt nach der Addition ausgeführt werden. Es gibt formal keine Abhängigkeit dazwischen, ein optimierender Compiler könnte den ganzen Code also so umschichten, dass es nicht mehr funktioniert.

    Ist es nicht ärgerlich, dass man - trotz topmoderner CPUs - bei jeder
    Berechnung, die man durchführt, statistisch nur ca. eine 50% Chance hat, dass
    das Ergebnis auch stimmt? In den anderen 50% der Fälle sorgt nämlich leider
    ein (mit Hoch-Sprachen-Mitteln schwer zu bekämpfender!) OVERFLOW für ein
    falsches Resultat.

    Stop mal, du willst doch nicht gerade von C auf alle Hochsprachen generell schließen, oder? Die fehlende Möglichkeit, auf arithmetische Überläufe reagieren zu können, ist eine bekannte Schwachstelle von C, und tritt in anderen Sprachen nicht zwangsläufig auf.

    Mit welchen Mitteln geht Ihr gegen OVERFLOWs vor? Gibt's da eventuell doch
    das eine oder andere (Hochsprachen-ANSI-C-) Mittel, um sich gegen den OVERFLOW
    erfolgreich zur Wehr zu setzen? 😕

    Mal anders gefragt: Was würdest du denn tun, wenn ein Überlauf abfragbar wäre? Eine Messagebox mit "Arithmetischer Überlauf, bitte hauen Sie dem Programmierer auf die Finger"? Darauf läuft es nämlich hinaus. Das ist auch der Grund, warum das in C nicht abgefangen wird. Du musst das Programm so schreiben, dass ein Überlauf von vornherein ausgeschlossen ist, indem du geeignete Datentypen wählst und die Eingaben auf geeignete Wertebereiche prüfst.



  • Nur rein aus Interesse, müsste ein standardkonformer C++ Compiler bei derartigen
    Overflows vorsichtshalber einen Ausnahme-JMP hinter jeder Berechnung generieren,
    die das Overflow-Flag setzen könnte ?
    Oder ließe sich so eine Overflow-Exception nicht mal mit Standard - C++ Mitteln
    fangen?



  • Überläufer schrieb:

    Nur rein aus Interesse, müsste ein standardkonformer C++ Compiler bei derartigen
    Overflows vorsichtshalber einen Ausnahme-JMP hinter jeder Berechnung generieren,
    die das Overflow-Flag setzen könnte ?

    Gegenfrage: muss jede Maschine, für die standardkonforme C++-Programme existieren, sowas wie ein Overflow-Flag kennen?



  • Überläufer schrieb:

    Oder ließe sich so eine Overflow-Exception nicht mal mit Standard - C++ Mitteln
    fangen?

    Genau, C++ macht hier genau das gleiche wie C, nämlich keine Exception.


Anmelden zum Antworten