interessantes phänomen
-
Die Reihenfolge der Abarbeitung der Teilausdrücke ist unspezifiziert, die hat nichts mit der Assoziativität der Operatoren zu tun.
-
Bashar schrieb:
Die Reihenfolge der Abarbeitung der Teilausdrücke ist unspezifiziert, die hat nichts mit der Assoziativität der Operatoren zu tun.
Aber mit dem Problem hier!
-
Aha. Eben hast du noch gesagt die Assoziativität wäre von rechts nach links. Das Problem hier ist in der Tat die unspezifizierte Abarbeitungsreihenfolge. Die gilt generell für alle Operatoren außer (nicht überladenen) &&, ||, Komma und ?:. Hauptsache das Ergebnis eines Teilausdruckes steht zur Verfügung wenn es benötigt wird.
-
das erinnert mich an meine informatik/Programmier vorlessungen in C++ da muss man auch das verhalten und Ausgaben anhand solcher Code Beispiele angeben;) nur noch bischen krassere block strukturen etc.
-
nun,bei mir läufts so wie erwartet (0123)
komischen compiler hast du dann wohl
-
seltsam schrieb:
nun,bei mir läufts so wie erwartet (0123)
komischen compiler hast du dann wohlWas für einen Compiler hast du denn? Der gcc und Visual C++ bringen bei mir die Ausgabe 3210.
-
Also mit dem Borland 6 krieg ich 1032 raus.
Versteh das aber net ganz. Ich mein die Funktion foo() wird doch jedesmal
neu gestartet, da müsste doch immer das selbe zurückkommen
Was meint ihr eigentlich mit Cout richtig klammern? Versteh net ganz was da geklammert werden soll

-
Schau dir nochmal an was static macht!

-
Verstehs auch nicht!
Ich bekomme "0132" ???
Mit VC80
-
Das ist einfach undefiniertes Verhalten. Das ist vergleichbar mit:
j = ++i + ++i;Das lernt man eigentlich in jedem C- oder C++-Grundkurs. Wann welcher Teilausdruck ausgewertet wird ist nicht definiert. Das hat nichts mit komischen Compilern zu tun, sondern ist einfach nicht definiert. Der Compiler kann sich entscheiden, zuerst die foo()-Aufrufe in welcher Reihenfolge auch immer auszuwerten und dann die operator<<-Aufrufe.
-
Dann wollen wir das mal aufdröseln:
cout<<foo()/*1*/<<foo()/*2*/; = operator<<( opoperator<<( cout, foo()/*1*/ ), foo()/*2*/ );Es ist klar definiert, daß alle benötigten Teilausdrücke berechnet werden, bevor sie zusammenkommen - insbesondere wird der innere op<<-Aufruf und der zweite foo() ausgeführt, bevor der äußere op<< drankommen kann. Aber es ist nicht vorgeschrieben, in welcher Reihenfolge die Parameter einer Funktion berechnet werden, also steht es einem Compiler frei, erst den unteren foo()-Aufruf und danach den inneren op<< abzuarbeiten (oder auch umgekehrt) - im ersten Fall lautet das Ergebnis "10", im letzten Fall "01".
(klarer Fall von undefniertem Verhalten)
-
Erläuternd dazu könnte man noch sagen - die Reihenfolge ist innerhalb einen Sequenzpunktes nicht definiert. Nach der Zeile cout << foo () << foo(); muss aber auf jeden Fall 10 oder 01 da stehen.
-
tntnet schrieb:
Das ist einfach undefiniertes Verhalten.
Unspezifiziert, nicht undefiniert. Jede mögliche Reihenfolge ist erlaubt, aber keine Nasendämonen.
-
C++-Standard; Kapitel 5 Expressions; Absatz 4
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual
expressions, and the order in which side effects take place, is unspecified.53) Between the previous
and next sequence point a scalar object shall have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.
The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full
expression; otherwise the behavior is undefined.
[Example:
i = v[i++]; // the behavior is unspecified
i = ++i + 1; // the behavior is unspecified
—end example]Gruß
Werner
-
Exceptional C++ schrieb:
Schreiben Sie niemals Code, der von der Reihenfolge der Auswertung von Funktionsargumenten abhängt.
-
Werner Salomon schrieb:
C++-Standard; Kapitel 5 Expressions; Absatz 4
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual
expressions, and the order in which side effects take place, is unspecified.53) Between the previous
and next sequence point a scalar object shall have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.
The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full
expression; otherwise the behavior is undefined.
[Example:
i = v[i++]; // the behavior is unspecified
i = ++i + 1; // the behavior is unspecified
—end example]Gruß
WernerOhne zu erwähnen, dass ein Funktionsaufruf ein Sequenzpunkt ist, könnte man diesen Abschnitt missverstehen.