Beide Versionen von ++
benötigen lvalues als Argumente, aber die Präfixversion gibt einen lvalue als Argument zurück, während die postfix-Version einen rvalue zurückgibt.
In beiden Fällen können Sie das gleiche Objekt nicht zweimal zwischen den einzelnen Sequenzpunkten ändern. Daher ruft Ihr "funktionierendes" Beispiel das Verhalten bei undefiniertem Verhalten auf. Die Ausgabe kann sein, was auch immer der Compiler tut. Wenn Sie nur aus Neugier fragen, ist das in Ordnung, aber wenn dies für Ihren tatsächlichen Code relevant ist, könnten Sie etwas falsch machen.
predecrement --a
dekrementiert a
und gibt dann a
selbst zurück. So können Sie dann weitermachen, wie Sie wollen, einschließlich einer Post-Dekrement.
postdecrement a--
dekrementiert a
, gibt Ihnen aber vor der Dekrementierung den Wert a zurück. Es gibt im Wesentlichen eine Kopie von a
. Sie können diese Kopie jedoch nicht vorherdepretieren. Es ist kein Wert, also gibt es nichts zu dekrementieren. Deshalb ist es ein Fehler.
Stellen Sie sich vor, dass predecrement einen Verweis auf a
zurückgibt und postdecrement als konstanten Wert zurückgibt.
%Vor%
Dies ist ein nicht definiertes Verhalten, da Sie dasselbe Objekt zweimal ohne einen dazwischenliegenden Sequenzpunkt ändern. Der Compiler muss beim Aufruf von UB nicht berichten - er kann in vielen Situationen nicht einmal UB erkennen. Aber wenn du die richtigen Warnungen einschaltest (und du solltest schauen, was dir geboten wird), kann es das manchmal tun.
%Vor%
Präfix-Dekrement erfordert einen Lvalue, aber Postfix-Dekrement gibt einen Rvalue zurück. Dies ist ein Fehler, bei dem der Compiler im Gegensatz zu nicht definiertem Verhalten erforderlich ist, um zu berichten.