i++



  • Hallo,

    kann mir jemand erklären, warum bei

    int i=1;
    printf("%d %d %d",i,i++,++i);

    3 2 3

    rauskommt

    für mich ist i++, i=i+1 also 2.

    Gruß



  • hm ich hätte 1 1 2 erwartet

    Edit oh natürlich 1 1 3



  • Die Auswertungsreihenfolge ist undefiniert:

    ISO/IEC 14882:2011 (n3337) schrieb:

    1.9 Program execution [intro.execution]

    [...]

    13 Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread (1.10), which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced. [ Note: The execution of unsequenced evaluations can overlap. —end note ] Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which. [ Note: Indeterminately sequenced evaluations cannot overlap, but either could be executed first. —end note ]

    14 Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated.8.

    15 Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations. —end note ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

    [ Example:

    void f(int, int);
    void g(int i, int* v) {
    i = v[i++];         // the behavior is undefined
    i = 7, i++, i++;    // i becomes 9
    i = i++ + 1;        // the behavior is undefined
    i = i + 1;          // the value of i is incremented
    f(i = -1, i = -1);  // the behavior is undefined
    }
    

    —end example ]

    [...]


  • Mod

    Swordfish schrieb:

    Die Auswertungsreihenfolge ist undefiniert:

    Nicht nur das. Die Reihenfolge ist sowieso undefiniert bei solch einem Ausdruck, aber hier bekommt man komplett undefiniertes Verhalten! Siehe Satz 15. Also ist nicht "nur" das genaue Ergebnis unbekannt, sondern der gute alte Fall, wo das Programm auch den Kater schwängern darf.



  • Ja, unglücklich formuliert.



  • Hallo!
    "++" ist ja ein Inkrement. Es spielt aber eine Rolle ob Du das ++ vor oder nach deiner Variablen setzt. Das nennt sich Postinkrement (i++) und Präinkrement (++i).



  • Thema verfehlt. Das Codeschnippsel von tom712 darf auch i = 42 machen, dir eine Pizza bestellen oder die Welt untergehen lassen. Es ist undefiniert und somit in dem Fall auch völlig egal ob pre- oder postinkrement.



  • areimund schrieb:

    Es spielt aber eine Rolle ob Du das ++ vor oder nach deiner Variablen setzt.

    Davon abgesehen, dass du das Thema verfehlt hast: Es spielt durchaus eine wichtige Rolle, ob es davor oder danach steht.



  • oenone schrieb:

    areimund schrieb:

    Es spielt aber eine Rolle ob Du das ++ vor oder nach deiner Variablen setzt.

    [...]: Es spielt durchaus eine wichtige Rolle, ob es davor oder danach steht.

    Wo siehst Du da jetzt einen Widerspruch, außer daß Du noch das prädikat wichtig verwendet hast?

    mfg Martin



  • @tom712, randa und areimund
    Mal etwas einfach formuliert:

    Hier kommen zwei Sachen zum tragen.
    Das eine ist die undefinierte Reihenfolge, in der die Paramter für printf ausgewertet werden.
    -> Es ist nicht klar, ob das i, das ++i oder das i++ zuerst berechnet wird.

    Das zweite ist der Sequence Point.
    Es ist auch undefiniert, wann das Ergebnis der Auswertung wieder nach i geschrieben wird.



  • mgaeckler schrieb:

    oenone schrieb:

    areimund schrieb:

    Es spielt aber eine Rolle ob Du das ++ vor oder nach deiner Variablen setzt.

    [...]: Es spielt durchaus eine wichtige Rolle, ob es davor oder danach steht.

    Wo siehst Du da jetzt einen Widerspruch, außer daß Du noch das prädikat wichtig verwendet hast?

    mfg Martin

    Er hat "keine" gelesen. Genau wie ich auch zuerst. ^^


  • Mod

    DirkB schrieb:

    Das zweite ist der Sequence Point.

    Gibt's doch gar nicht 🙂



  • Gabs doch mal ... und gemeint ist heute genau dasselbe. 🙂



  • SeppJ schrieb:

    DirkB schrieb:

    Das zweite ist der Sequence Point.

    Gibt's doch gar nicht 🙂

    Du Schelm!



  • Jetzt wird's interessant:

    int i=1;
    printf("%d %d %d",(i,i++,++i));
    

    3 0 201718260



  • ernsthaft?



  • EOP schrieb:

    Jetzt wird's interessant:

    int i=1;
    printf("%d %d %d",(i,i++,++i));
    

    3 0 201718260

    Kommaoperator und Auslesen unbelegten Stackspeichers.

    (Aber hab den GCC schon dabei erwischt, wo er was gesehen hat, was nicht dem Standard entspricht, und es einfach wegoptimierte.

    short i=0;//mit unsigned gehts
    for(wasanderes){
       if(!++i) cout<<…<<flush;//Statusausgabe alle 60000 Durchläufe
    //Pustekuchen, Standardchen verlangt keinen signed Integerüberlauf
    }
    

    )



  • _matze schrieb:

    mgaeckler schrieb:

    oenone schrieb:

    areimund schrieb:

    Es spielt aber eine Rolle ob Du das ++ vor oder nach deiner Variablen setzt.

    [...]: Es spielt durchaus eine wichtige Rolle, ob es davor oder danach steht.

    Wo siehst Du da jetzt einen Widerspruch, außer daß Du noch das prädikat wichtig verwendet hast?

    mfg Martin

    Er hat "keine" gelesen. Genau wie ich auch zuerst. ^^

    Jepp, bekenne mich schuldig. Sorry! 😮



  • Swordfish schrieb:

    ernsthaft?

    Yo.
    Hab anfangs eigentlich nur probiert, ob man das mit klammern austricksen/umgehen kann. Kam immer nur Quatsch dabei raus.

    EDIT:
    Die Versuche mit 3, 4 Klammerpaaren waren genauso Sch...



  • Volkard, wieso bist du kein Moderator mehr?


Anmelden zum Antworten