Reihenfolge der Auswertung von Ausdrücken



  • int i=2

    cout << i++ << i << ++i << i <<endl;

    Denkt erst mal nach nicht ausprobieren für die Leute mit Erfahrung sicher kein Problem 😉

    MFG eiskalt



  • Der Standard läßt die Reihenfolge, in der Funktionsargumente ausgewertet werden, unspezifiziert.



  • Schön heist dass dass deiner Meinug nach alles Mögliche zwischen 2 und 4 rauskommen könnte?

    MFG eiskalt



  • 2344

    Dieser Ausdruck wird von links nach rechts verarbeitet. Wozu die Frage???



  • cout << i++ << i << ++i << i <<endl;
    

    entspricht doch IMHO:

    ((((cout << i++) << i) << ++i) << i) << endl;
    

    Da wird doch jedesmal der operator<<(int) aufgerufen. Niemals eine Funktion mit mehreren Parametern, oder täusche ich mich da?



  • Zuerst wird 2 angezeigt und dann 4!!!



  • @ags
    bei mir kommt nat. 4444 raus. 😃

    @cd9000
    ist

    std::ostream& operator << (std::ostream&, int)
    

    Keine funktion mit mehreren Parametern?

    Ich denke, bashar hat schon ziemlich recht.



  • also erster wert 2 und letzter 4, dazwischen 3er



  • Der Borlandbuilder bringt bei mir 3332 und der g++ auch.

    und ich bilde mir ein das dieser ausdruck nicht von links nach rechts abgearbeitet wird.

    IMHO wird doch das ++i als erstes im Ausdruck ausgewertet oder nicht und dann der Rest spricht die Ausgabe.

    Hab ich aus einem Lehrbuch C++ Entwicklung mit Linux 😉



  • Hallo,
    eine wichtige Antwort hat Bashar schon gegeben.
    Allerdings hat der Aufruf hier nicht nur *implementations-spezifisches* sondern auch *undefniertes Verhalten*

    entspricht doch IMHO:

    ((((cout << i++) << i) << ++i) << i) << endl;

    Oder funktional:

    <<(<<(<<(<<(cout, i++), i), ++i),i)
    

    Die Argumente einer Funktion müssen *vor* dem Funktionsaufruf ausgewertet werden. Jeder Funktionsaufruf führt einen sequence point ein.

    Wie bereits gesagt, gibt es aber keine Vorschrift die festlegt in welcher Reihenfolge Funktionsparameter ausgewertet werden. Theoretisch könnten sie auch alle parallel ausgewertet werden bzw. alle vier bevor die erste Funktion aufgerufen wird. Da i hier zweimal verändert wird, kann es passieren, dass beide Änderungen *vor* einem sequence point geschehen. Und das produziert undefiniertes Verhalten.
    Frei nach der Regel: "If any order of evaluation
    produces undefined behavior, the statement produces undefined behavior".

    Hab ich aus einem Lehrbuch C++ Entwicklung mit Linux

    Nicht alles was in Lehrbüchern steht ist auch richtig.

    Also um es noch mal deutlich zu sagen: Es ist völlig unnötig sich hier den Kopf zu zerbrechen. Man *kann* nicht vorhersagen was hier ausgegeben wird. In diesem Fall *kann* alles passieren. In anderen Fällen (die nur implementations-spezifischess Verhalten haben) kann jede beliebige Permutation der Werte rauskommen.

    [ Dieser Beitrag wurde am 03.02.2003 um 16:28 Uhr von HumeSikkins editiert. ]



  • Naja das Beispiel war nicht als gutes Beispiel gedacht sondern eher als negativ ich habs halt mal ausprobiert und war von dem Ergebniss eben überrascht und leider konnte mir mein AWP-Lehrer da auch nicht weiterhelfen 😉

    THX eiskalt



  • Wie oft wird diese Frage gestellt? In die FAQ mit allem was damit zu tun hat :D.



  • Hume: Bei welcher Auswertungsreihenfolge wird i denn zweimal zwischen 2 Sequenzpunkten modifiziert? Ich seh auf die Schnelle keine und denke auch, dass es "sicher" ist. Das jeweils erste Argument einer der Funktionen ist ja selbst wieder ein Funktionsaufruf und daher ein Sequenzpunkt ... es könnte höchstens sein, dass i gleichzeitig gelesen und geschrieben wird, und das ist kein UB.



  • @Bashar
    "Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored."

    Wenn jetzt alle is *vor* den Funktionsaufrufen ausgewertet werden, liegt dazwischen kein Sequence Point. Hier wird aber der Wert von i verändert und gelesen und zwar nicht "to determine the value to be stored."

    Eine sehr schöne Erklärung von John Potter.

    Und eine noch schönere von Dan Saks. Die ist allerdings deutlich länger.

    [ Dieser Beitrag wurde am 04.02.2003 um 10:37 Uhr von HumeSikkins editiert. ]



  • hm ich war irgendwie blind ... einfaches von rechts nach links auswerten läßt es schon knallen. 🙄


Anmelden zum Antworten