[C++] GCC warnt "sequence point"

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

[C++] GCC warnt "sequence point"

Beitrag von Schrompf »

Kurze Frage zu einer GCC-Warnung. Der Code ist u.A. dieser:

Code: Alles auswählen

for( schleife )
  *tmp++ = (uint8_t) (*tmp + *(tmp - pxlbreite))&255;
GCC spricht dazu:
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.

Danke.

Bye, Thomas
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Alexander Kornrumpf
Moderator
Beiträge: 2113
Registriert: 25.02.2009, 13:37

Re: [C++] GCC warnt "sequence point"

Beitrag von Alexander Kornrumpf »

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?
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [C++] GCC warnt "sequence point"

Beitrag von xq »

Schreib doch einfach das Zeigerinkrement via Komma-Operator in die for-schleife, das dürfte sicherer sein:

Code: Alles auswählen

for( schleife, tmp++ )
  *tmp = (uint8_t) (*tmp + *(tmp - pxlbreite))&255;
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…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
Krishty
Establishment
Beiträge: 8240
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] GCC warnt "sequence point"

Beitrag von Krishty »

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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: [C++] GCC warnt "sequence point"

Beitrag von Sternmull »

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.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [C++] GCC warnt "sequence point"

Beitrag von Schrompf »

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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Antworten