Frage zu increment



  • @Wade1234 sagte in Frage zu increment:

    also eigentlich (nach meinem wissen) ist es so, dass der post-inkrement nach der zuweisung ausgeführt, bzw. der ausdruck erst ausgewertet und dann erhöht wird.

    Es ist undefiniertes Verhalten.
    Jeder Compiler kann da machen, was er will.
    Je nach Optimierungsstufe kann das Ergebnis anders ausfallen.

    Was würdest du bei x = x++ + x++ erwarten?

    Das Stichwort dazu wäre Sequence Point



  • @DirkB sagte in Frage zu increment:

    Was würdest du bei x = x++ + x++ erwarten?

    naja 6 bei x = 2, weil 2 + 2 + 1 + 1 nach meiner rechnung eben = 6 ist. im prinzip ist es ja eigentlich auch egal, ob da auf der cpu 2 + 2 + 1 + 1, oder 3 + 3, oder 3 + 2 + 1 oder 2 + 1 + 2 + 1 oder was auch immer gerechnet wird.

    mein buch sagt jedenfalls genau das aus: https://www.bilder-upload.eu/bild-d48b0d-1572510061.jpg.html

    aber ich habs eben mal durch den clang geschickt und dieser meckert rum und gibt 5 aus. 🙄 ein grund mehr, solche spielereien einfach bleiben zu lassen und eine anweisung pro zeile zu verwenden.🤨


  • Mod

    @Wade1234 sagte in Frage zu increment:

    @DirkB sagte in Frage zu increment:

    Was würdest du bei x = x++ + x++ erwarten?

    naja 6 bei x = 2, weil 2 + 2 + 1 + 1 nach meiner rechnung eben = 6 ist. im prinzip ist es ja eigentlich auch egal, ob da auf der cpu 2 + 2 + 1 + 1, oder 3 + 3, oder 3 + 2 + 1 oder 2 + 1 + 2 + 1 oder was auch immer gerechnet wird.

    mein buch sagt jedenfalls genau das aus: https://www.bilder-upload.eu/bild-d48b0d-1572510061.jpg.html

    aber ich habs eben mal durch den clang geschickt und dieser meckert rum und gibt 5 aus. 🙄 ein grund mehr, solche spielereien einfach bleiben zu lassen und eine anweisung pro zeile zu verwenden.🤨

    Ich glaube, du hast das Problem nicht wirklich verstanden...



  • @SeppJ naja doch: die erwartungshaltung wäre, dass das so funktioniert, wie von mir beschrieben, weil postfix "führe nach der auswertung aus" bedeutet / bedeuten soll und zuweisung "werte den ausdruck auf der rechten seite aus und schreibe den wert auf die linke seite" bedeutet / bedeuten soll.

    die realität sieht so aus, dass der compiler das so machen kann, aber nicht so machen muss und der clang in meinem speziellen fall das auch nicht so machen wird, weil der standard das laut eurer aussage nicht so einfordert, was ich eigentlich ein bisschen komisch finde.


  • Mod

    @Wade1234 sagte in Frage zu increment:

    @SeppJ naja doch: die erwartungshaltung wäre, dass das so funktioniert, wie von mir beschrieben, weil postfix "führe nach der auswertung aus" bedeutet / bedeuten soll und zuweisung "werte den ausdruck auf der rechten seite aus und schreibe den wert auf die linke seite" bedeutet / bedeuten soll.

    Nein, eben nicht. Wie kommst du darauf? Du verweist auf dein Buch, aber ich kann deinem Buch keinen Vorwurf machen, da steht nichts dergleichen drin.

    @Wade1234 sagte in Frage zu increment:

    die realität sieht so aus, dass der compiler das so machen kann, aber nicht so machen muss und der clang in meinem speziellen fall das auch nicht so machen wird, weil der standard das laut eurer aussage nicht so einfordert, was ich eigentlich ein bisschen komisch finde.

    Auch nicht. Das ist nicht "da kommt irgendwas compilerabhängiges raus", dass ist undefiniert. Das ist das schlimmste, was du haben kannst. Da kannst du keine Erwartungen anlegen, was "in der Realität" rauskommt. In der "Realität" sind da schon krasse Dinge passiert, weil Leute so gedacht haben wie du.



  • @SeppJ also ich interpretiere es jedenfalls so.


  • Mod

    @Wade1234 sagte in Frage zu increment:

    @SeppJ also ich interpretiere es jedenfalls so.

    Und deswegen ist es wichtig, dass du genauer liest und genau mitdenkst. Denn das steht da nicht. Du machst einen nicht gerechtfertigten Gedankensprung von "nach der Auswertung des Postfix" zu "nach dem nächsten Sequenzpunkt".

    Da der Computer immer ganz genau tut, was du ihm sagst, und nicht das, was du meinst, ist es wichtig, dass du die Regeln ganz genau liest und verstehst, und da keine eigene Interpretation rein bringst.



  • @Wade1234 sagte in Frage zu increment:

    also ich interpretiere es jedenfalls so

    Das Problem hier ist die Zuweisung an x innerhalb des Sequence Points (der endet hier beim ; )

    clang mag hier auf der rechten Seite 2+3 auswerten (da wäre x dann 4. Dann folgt die Berechnung und Zuweisung an x. Also 5

    Ist aber auch egal, da es undefiniert ist.



  • @Wade1234
    Postfix garantiert dass der Wert der inkrementierten/dekrementierten Variable (nicht! des gesamten Ausdrucks) vor dem Ändern der Variable ermittelt wird, und das Ändern der Variable dann danach passiert. Eine Garantie dass das Ändern der Variable noch weiter verzögert wird, z.B. bis nach dem Assignment in diesem Beispiel, gibt es nicht.

    D.h. es könnte 2 als Wert ermittelt werden, dann x inkrementiert, und dann erst das Assignment x = 2 durchgeführt.

    Welche weiteren Regeln es diesbezüglich noch gibt hat sich soweit ich weiss auch zumindest einmal mit C++11~17 geändert. Das sind Regeln die ich nicht auswendig kenne. Ich schreibe solchen Code nicht. Macht doch überhaupt keinen Sinn wenn man beim Code Lesen dauernd über Konstrukte stolpert wo man so esoterische Regeln kennen muss um zu verstehen ob sie überhaupt definiertes Verhalten haben. Und es ist viel zu leicht damit Mist zu bauen.



  • @DirkB Gibt es Sequence-Points in C++11 noch? Ich dachte das wurde durch anders formulierte Regeln ersetzt.


  • Mod

    @hustbaer sagte in Frage zu increment:

    @DirkB Gibt es Sequence-Points in C++11 noch? Ich dachte das wurde durch anders formulierte Regeln ersetzt.

    Es ist jetzt anders formuliert, ja, aber es kommt aufs gleiche raus. Jetzt gibt es Aussagen darüber, welche Art von Effekten "vor" oder "nach" anderen Effekten auftreten. Da hier aber alle Effekte von der gleichen Art sind und auf dem selben Objekt arbeiten, ist das Verhalten nach wie vor undefiniert.

    PS: In C++17 hat man es aber noch feiner unterteilt, da fallen manche dieser Beispiele weg. i = i++; ist jetzt wohldefiniert. i = i++ + ++i; aber nach wie vor nicht.

    PPS: Der Preis dafür ist, das aus 5 Regeln nun 21 geworden sind 🙀



  • @SeppJ Danke 🙂
    BTW: Was heisst "vodrukeln"?


  • Mod

    @hustbaer sagte in Frage zu increment:

    @SeppJ Danke 🙂
    BTW: Was heisst "vodrukeln"?

    Das ist so etwas wie verdräkeln, aber weniger kubunt.



  • @SeppJ Ah, verdammt. Wenn mir der Name dieser überaus geheimen Geheimsprache einfallen würde könnte ich jetzt die Regeln nachlesen.



  • @SeppJ sagte in Frage zu increment:

    PPS: Der Preis dafür ist, das aus 5 Regeln nun 21 geworden sind 🙀

    Naja dafür sind die aber halbwegs einfach.


  • Mod

    @hustbaer sagte in Frage zu increment:

    @SeppJ sagte in Frage zu increment:

    PPS: Der Preis dafür ist, das aus 5 Regeln nun 21 geworden sind 🙀

    Naja dafür sind die aber halbwegs einfach.

    Naja. Ist so meiner Meinung nach eher so wie wenn man aus

    if isalpha(c)
       prio = 1;
    else if isdigit(c)
       prio = 2;
    

    stattdessen

    if c == 'a'
       prio = 1;
    else if c == 'b'
       prio = 2;
    // ...
    else if c == 'z'
       prio = 26;
    else if c == '0'
       prio = 27;
    // ...
    

    macht.



  • @SeppJ Ja verstehe schon was du meinst. Andrerseits... wer Code schreibt wo das ne Rolle spielt, der ist mMn. selbst schuld. Klar, dazu muss man wissen was evtl. problematisch werden könnte. Aber man muss nicht die ganzen Regeln kennen wo es dann doch definiert ist.



    1. Die Compiler warnen. Rant: ich halte es für einen fragwürdig, dass nicht ein Mindestset an Warnungen per default an ist bei gcc/clang. "may be undefined" -> warum kann man da nicht einen Compilefehler draus machen? Oder hat die sequence point Fehlermeldung false positives?

    2. Wenn man den Code mal in godbolt kippt und die Compiler durchklickt, sieht man, dass ältere gcc (4.x) in der Tat 6 liefern und neuere 5. (jeweils mit -O2) zumindest.



  • irgendwie gibt es jetzt noch einen grund mehr, nur eine anweisung pro zeile zu machen. also man muss schon ziemlich wirr sein, wenn man diese ganzen regeln als endanwender auswendig lernt.☠

    außerdem liefert der clang doch eine warnung und der gcc wird das auch tun (es wundert mich sowieso, warum es immer heißt "aktivier doch mal die warnungen!"; die sind nirgendwo ausgeschaltet.):

    test.c:8:7: warning: multiple unsequenced modifications to 'x' [-Wunsequenced]
            x = x++;
              ~  ^
    
    
    test.c:8:7: warning: multiple unsequenced modifications to 'x' [-Wunsequenced]
            x = x++ + x++;
    


  • @Wade1234 sagte in Frage zu increment:

    es wundert mich sowieso, warum es immer heißt "aktivier doch mal die warnungen!"; die sind nirgendwo ausgeschaltet.):

    Alle sind nicht aktiviert, selbst bei -Wall nicht.
    Und bei VS ist i. A. auch nicht der höchste Warnlevel aktiv.


Anmelden zum Antworten