gcc hat geschrieben:warning: operation on 'tmp' may be undefined [-Wsequence-point]
Warum? Da werden zwei Bytes gelesen, verrechnet, dann geschrieben, und zum Schluss der Zeiger um eins weitergesetzt. Nach meinem Verständnis ist die Reihenfolge hier eindeutig definiert.
Es beruhigt mich, dass du dir über die Reihenfolge sicher bist, ich will auch nicht bezweifeln, dass du recht hast. Ich dagegen nutze das nicht täglich und mir wird beim lesen Angst und Bange.
Wäre es wirklich so ein Drama das Zeigerinkrement for the benefit of the reader in der nächsten Zeile zu machen?
EDIT:
Die Reihenfolge ist nicht unbedingt so wie du es da hinschreibst, der Compiler wird bei Optimierungen eventuell das Zeigerinkrement machen, bevor er den Code dahinter ausführt, weil performanter
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…
Hmmm. GCC hat recht – die Auswertungsreihenfolge und -anzahl ist nicht definiert; GCC könnte erst das Inkrement durchführen und tmp für das Laden des Wertes erneut auswerten.
Felix’ Vorschlag ist gut. Wenn ich ihn ergänzen könnte: tmp[0] + tmp[-pixelbreite] ist deutlicher als *tmp + *(tmp - pxlbreite). Könnte aber sein, dass die Versionen unter Visual C++ unterschiedlich schnell sind (LEA vs SUB).
Zuletzt geändert von Krishty am 20.02.2015, 20:21, insgesamt 1-mal geändert.
Die Vorredner haben recht. Ich vermute das es hier einfach die Intuition ist die hier in die Irre führt: Wenn man sich die Zeile anguckt dann denkt man "es wird erst mal die rechte Seite ausgerechnet, und das dann der linken Seite zugewiesen". Das ist aber in C++ eben nicht so weil ein "=" keine Reihenfolge in der Abarbeitung vorgibt. Statt dessen gilt auch für diesen Operator (im Gegensatz zu &&, || und : ?) die Regel das alle Operanden eines Ausdrucks (also auch einer Zuweisung) in beliebiger Reihenfolge ausgewertet werden dürfen. Also ist nicht definiert wann das postfix increment auf der linken Seite durchgeführt wird. Detailliert wäre das z.B. hier nachzulesen.
Ok, da war ich wirklich meiner Intuition aufgesessen. Und schön, dass nach zehn Jahren produktivem Einsatz dieses Codes in Visual Studio jetzt erst der GCC mich darauf hinweist. Nuja, das ist der Vorteil an manueller Linux-Portierung - ich lerne gerade viel dazu.