Frage zu <<
-
Hallo Forum,
warum geht:
cout << "a" << "b" << "c";
und
cout << myfunc() << myfunc() << myfunc();
gibt Probleme bei der Auswertungsreihenfolge?Vielen Dank
Persy
-
Weil es darauf ankommt was myfunc() zurück gibt, genauer gesagt welchen Typ es zurück gibt. Wenn es keiner der Standardtypen ist, mußt du den <<-Operator für ostream überladen, was sehr einfach ist. Dann funktioniert das auch.
-
Artchi schrieb:
Weil es darauf ankommt was myfunc() zurück gibt, genauer gesagt welchen Typ es zurück gibt. Wenn es keiner der Standardtypen ist, mußt du den <<-Operator für ostream überladen, was sehr einfach ist. Dann funktioniert das auch.
Auch mit Standardtypen funktioniert es nicht, sondern wird stack-mäßig von hinten aufgerollt. Ich kriege also die genau umgekehrte Reihenfolge. Zumindest beim MS-Compiler (keine Ahnung, ob sowas implementierungsspezifisch ist).
-
Persy schrieb:
warum geht:
cout << "a" << "b" << "c";
und
cout << myfunc() << myfunc() << myfunc();Weil operator<<() den Stream als Ergebnis liefert:
std::stream &operator<<(std::stream &lhs, const char *rhs) { // rhs nach lhs ausgeben return lhs; }Persy schrieb:
gibt Probleme bei der Auswertungsreihenfolge?
Edit: S. _matze und Artchi
Stefan.
-
Persy schrieb:
warum geht:
cout << "a" << "b" << "c";
und
cout << myfunc() << myfunc() << myfunc();
gibt Probleme bei der Auswertungsreihenfolge?Was für Probleme denn? Ich rate mal, dass Dein myfunc Seiteneffekte besitzt und unterschiedliche Ergebnisse liefert. ZB so etwas:
int myfunc() { static int i=0; return ++i; }Und wahrscheinlich würdest Du hier folgende Ausgabe erwarten:
123Allerdings wird nirgendswo im C++ Standard festgelegt (bis auf ein paar Ausnahmen), in welcher Reihenfolge Teilausdrücke ausgewertet werden. Daher kannst Du Dich hier auf nichts verlassen.
Der Compiler kann das intern so zerlegen
tmp1 = myfunc() tmp2 = myfunc() tmp3 = myfunc() cout << tmp1 << tmp2 << tmp3oder aber so
tmp3 = myfunc() tmp2 = myfunc() tmp1 = myfunc() cout << tmp1 << tmp2 << tmp3oder aber so
tmp2 = myfunc() tmp1 = myfunc() sref = cout << tmp1 << tmp2 tmp3 = myfunc() sref << tmp3...ist alles erlaubt...
Gruß,
SP
-
Das war gerade in der Vorlesung. Es hieß die Reihenfolge der Abarbeitung wäre nicht genau definiert. Hier ein Beispiel:
#include <iostream> using namespace std; char myfunc(int a) { return (char)(64 + a); } int main() { cout << "a" << "b" << "c" << endl; cout << myfunc(1) << myfunc(2) << myfunc(3) << endl; return 0; }Es funktioniert jedoch wie vorgesehen (g++ Kompiler): "abc" und dann "ABC"
Habt Ihr ne Ahnung was da gemeint ist?EDIT: Ich sehe gerade Sebastians Antwort. Wenn die Auswertungsreihenfolge unklar ist, wäre das aber nicht intuitiv. Laut Matze würde der MS Kompiler CBA ausegeben. Das wäre ziemlich unerwartet. Wenn der Prof das in der Vorlesung extra erwähnt hat muß man sich bei C++ wohl daran gewöhnen...
Vielen Dank

Persy
-
#include <iostream> using namespace std; char glob='A'; char myfunc(int a) { return glob++; } int main() { cout << "a" << "b" << "c" << endl; cout << myfunc(1) << myfunc(2) << myfunc(3) << endl; return 0; }Ausgabe CBA
Und jetzt denk nach, warum Dein Prog bei jeder Auswertungsreihenfolge ABC ausgibt und deswegen gar kein diesbezüglicher Test ist.
-
Stimmt, CBA jetzt auch bei mir. Da habe ich die static oder globale Veriable vergessen. Wie bei Volkard ist es richtig. In Unterausdrücke werden also bei beiden Kompilern in umgekehrter Reihenfolge (also von rechts nach links) ausgewertet.
Vielen Dank

Persy