Merkwürdiges Verhalten bei Überlauf. Unterschied x+1 / ++x



  • Hallo Leute,

    #include <iostream>
    #include <climits>
    
    using namespace std;
    
    int main(){
    
    	long x(LONG_MAX);
    
    	cout << "LONG_MAX ist: " << x << "\tLONG_MAX ++ ist: " << ([b]x+1[/b]) << endl;
    	return 0;
    }
    

    Der Code soll einen Überlauf provozieren. Tut er auch wie er soll; Ausgabe: +2147483647 und -2147483648

    cout << "LONG_MAX ist: " << x << "\tLONG_MAX ++ ist: " << ([b]++x[/b]) << endl;
    

    nun erhält man zwei negative Werte (?).
    Versteh ich nicht, wie kommt es das hier ein Unterschied zwischen x+1 und ++x besteht ??

    cout << "LONG_MAX ist: " << x << "\tLONG_MAX ++ ist: " << ([b]x++[/b]) << endl;
    

    und bei x++ ist das Verhalten nochmal unerwartet: hier ist die Ausgabe -2147483648 und +2147483647 😕

    Jetzt dachte ich es liegt vielleicht daran das die Variable mit einer Konstanten initialisiert wurde,
    aber auch wenn das Limit als Zahl angegeben wird tritt das Verhalten auf.

    und das Verhalten tritt auch auf wenn x mit einer Zahl initialisiert wird die ausreichend unterhalb des Limit ist z.B. 2147483638...

    Hat jemand eine Idee wie das kommt?
    Danke im Voraus
    S.



  • nun erhält man zwei negative Werte (?) [...] und bei x++ ist das Verhalten nochmal unerwartet:

    Das hatten wir doch letztens erst in mehreren Threads ...

    Zum Beispiel:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-242991.html
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-242967.html



  • Jopp - das Verhalten ist undefiniert - hatten wir in den letzten 2 Tagen 2mal, das Thema...

    Thread-Titel waren

    "Dekrement"
    bzw
    "Inkrement / Dekrement"
    glaube ich ^^

    kannst ja mal danach suchen - im erstgenannten steht auch genau, warum...

    bb



  • ja, den ersten hatte ich nicht gesehen..

    und das Verhalten tritt auch auf wenn x mit einer Zahl initialisiert wird die ausreichend unterhalb des Limit ist z.B. 2147483638...

    nicht ganz.. 🙄 Der Term wird von rechts nach links abgearbeitet...
    dann ist das Verhalten stimmig.

    und sagt mal, wie ist das nun, die Reihenfolge bei Verwendung von cout ist die nun festgelegt oder nciht?

    Thanks!



  • Spacepilot schrieb:

    und sagt mal, wie ist das nun, die Reihenfolge bei Verwendung von cout ist die nun festgelegt oder nciht?

    Thanks!

    Das hat nichts mit std::cout oder der Operator-Priorität zu tun. Der Compiler darf seine Operanden in der Reihenfolge auswerten, die ihm am besten passt - er muss den Ausdruck anschliessend nur so zusammenfügen, dass er der geforderten Programmlogik entspricht.

    Und die Programmlogik ist eben so lange definiert, wie du dich an die Regeln hältst. Sobald zwischen zwei Sequenzpunkten mehrmals auf eine Variable zugegriffen wird, die in diesem Ausdruck verändert wird, ist das Verhalten undefiniert.



  • ahh, ja, danke!
    wer lesen kann ist klar im Vorteil..

    Tatsache ist, auf eine Variable darf zwischen zwei Sequenzpunkten (dazu gehören zum Beispiel die Operatoren &&, || und ,) nicht mehrfach zugegriffen werden, wenn sie in dieser Zeit verändert wird.

    Gruß S.


Anmelden zum Antworten