Herb Sutters Quick Poll: Order of evaluation?



  • Hab 00 genommen, unter der Annahme, dass danach gefragt war, wie man das lösen sollte wenn man es mal angehen würde. Muss man aber nicht, ich finde es vollkommen in Ordnung, dass das undefiniert ist.



  • 10
    Weil: Man muss nicht alles was in C++ crazy und freaky ist auch beibehalten.

    EDIT: ARGH! Ich meine natürlich 10, nicht 01. Also v[0] == 1 halt.


  • Mod

    10 überzeugt vielleicht in diesem einfachen Beispiel, bei komplizierteren Sachen ist das auch nicht mehr so klar.
    Ein einfach zu merkende Regel würde einfach der Assoziativität der Operatoren folgen: damit 01

    betrachte z.B.

    v[i++]=v[i++]=v[i++];
    


  • camper schrieb:

    Ein einfach zu merkende Regel würde einfach der Assoziativität der Operatoren folgen: damit 01

    Soll mir auch Recht sein.

    ps: Und ja, dein Argument ist gut. Hatte ich nicht weit genug gedacht.
    Und genaugenommen ist mir alles Recht ausser UB. Also unspecified oder die "eins von den dreien" Variante, alles OK, so lange nicht UB.



  • um der linken Seite etwas zuzuweisen, muß erst die rechte Seite ausgewertet sein, danach ist i = 1, dann wird zugewiesen, also v[1] = 1 und v[0] unspecified - das ist, was ich erwarten würde.



  • @großbuchstaben
    Wieso v[0] unspecified?
    Wurde ja mit 0 initialisiert.
    Wenn v[1] == 1 definiertes Verhalten sein soll, dann muss da mMn. auch v[0] == 0 garantiert sein.


  • Mod

    Ein einfach zu merkende Regel würde einfach der Assoziativität der Operatoren folgen: damit 01

    Das ist doch bei weitem die schwachsinnigste Option, oder nicht? Warum sollte i++ zweimal 1 ergeben!?



  • hustbaer schrieb:

    @großbuchstaben
    Wieso v[0] unspecified?
    Wurde ja mit 0 initialisiert.

    oops, hab die erste Zeile übersehen



  • obwohl - ist die erste Zeile nicht ohnehin überflüssig? vector dürfte doch den Standard-Konstruktor von int rufen.



  • Man erwartet intuitiv, dass die Argumente einer Funktion von links nach rechts ausgewertet werden.

    Hier hat man

    operator=(v.operator[](i.operator++(0)), i.operator++(0));
    //                     Wert=0, i=1       Wert=1, i=2
    

    Also Ausgabe "10".



  • Arcoth schrieb:

    Ein einfach zu merkende Regel würde einfach der Assoziativität der Operatoren folgen: damit 01

    Das ist doch bei weitem die schwachsinnigste Option, oder nicht? Warum sollte i++ zweimal 1 ergeben!?

    Jo. 🙂


  • Mod

    Bashar schrieb:

    Hab 00 genommen, unter der Annahme, dass danach gefragt war, wie man das lösen sollte wenn man es mal angehen würde. Muss man aber nicht, ich finde es vollkommen in Ordnung, dass das undefiniert ist.

    Aus dem Grund habe ich für Festplatte formatieren gestimmt. Ich befürchte mehr Schaden als Nutzen, wenn man dieses Möchtegernproblem angeht und will kein Signal senden, dass ich mir ein anderes Verhalten wünschen würde.



  • 42

    Nene, ich bin für 10, also dass die Inkrements von links nach rechts aufgelöst werden, da dies meiner Leserichtung entspricht, haben die Araber halt Pech^^

    v[0] = 1; // Ausgabe 10
    


  • Undefiniert. Man denke nur mal an das ganze Chaos, das mitgebracht werden würde, wenn man den Postinkrement-Operator mal selbst implementiert; wer zwingt einem denn dazu, auch wirklich den ehemaligen Zustand zurückzugeben?

    00 ist quatsch. Soll also erst zweimal (Reihenfolge?) der Rückgabewert von i++ eingesetzt (wobei dann eine Kopie erstellt werden muss, weswegen ein Kopierkonstruktor vonnöten ist; Willkür) und dann noch ein drittes (wer rechnet schon damit?) i++ berechnet werden?

    10 ist für mich noch irgendwie verständlich. Dann muss aber auch die Auswertungsreihenfolge von Funktionen definiert werden (in v[i++] = i++; ist v[i++] ja auch nur Argument von operator= ). Und das verhindert afaik gewisse Compileroptimierungen (bin mir nicht mehr sicher, kein Gewähr).



  • Ich schließe mich der 10er Sekte an.
    IMO ist es auf den ersten Blick am natürlichsten, ich lesen den Source Code schließlich auch von links nach rechts.



  • Ich bin für 00.
    Die Assoziativität vom operator= ist right-to-left, also auch die Auswertung.

    Und das Ganze bezieht sich vermutlich auf das Proposal, was die Auswertungsreihenfolge definieren will.



  • Nathan schrieb:

    Die Assoziativität vom operator= ist right-to-left, also auch die Auswertung.

    Was hat das miteinander zu tun?
    Bedeutet das nun etwa, dass du erwartest, dass bei

    f()+g()*h();
    

    zuerst g(), dann h() und dann f() ausgeführt wird?



  • lefttoright schrieb:

    Nathan schrieb:

    Die Assoziativität vom operator= ist right-to-left, also auch die Auswertung.

    Was hat das miteinander zu tun?
    Bedeutet das nun etwa, dass du erwartest, dass bei

    f()+g()*h();
    

    zuerst g(), dann h() und dann f() ausgeführt wird?

    Ja

    Später Edit um das zu erklären:
    Wenn man kopfrechnen muss:

    5 + 3 * 4
    

    Rechnet man ja auch erst 3 * 4 und addiert dann 5. Dort ist es dasselbe.
    Es ist nur logisch, sich nach Priorität und Assoziativität auszurichten.


Anmelden zum Antworten