Go Down

Topic: Warnung bei ++index % maxwert, nicht aber bei (index +1) % maxwert (Read 245 times) previous topic - next topic

postmaster-ino

Hi

Bin soeben über einen Sketch von agmue gestolpert, wo Er einen Index hochzählt und gleichzeitig auf einen Maximalwert begrenzt.
Er nutzt dafür das Konstrukt:
Code: [Select]
index = (index + 1) % anzWerte;
Selber nutze ich Ähnliches - meiner Meinung genau das Gleiche, wirft aber eine Warnung
Code: [Select]
index = ++index % anzWerte;
C:\...\arduino_modified_sketch_787353\sketch_dec31a.ino:19:31: warning: operation on 'index' may be undefined [-Wsequence-point]
     index = ++index % anzWerte;
                               ^

Worin unterscheidet sich ++index von (index + 1) und warum ist meine Variante 'undefiniert'?
Funktioniert wie gewünscht, index wird zuerst inkrementiert, dann per Modulo mit dem maximal-Wert verrechnet.
Raus kommt ein um 1 erhöhter Index, Der an der hinteren Grenze (auf Null) umgebrochen wird.
Unschön sind halt die Warnungen, Die ich zu jeder dieser Berechnungen bekomme - benutze an 5 Stellen dieses Konstrukt, um Daten in je einen Ringspeicher (IN/OUT) zu schreiben (3x) oder auszulesen (2x).

MfG

*Edit*
Sollte hier keinen Einfluss haben, im aktuellen Fall geht's um einen Uno

PS: die funktionierende (und warnungsfreie) Version, danke an DerFips, sieht so aus:
++index = index % anzWerte;
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

Serenifly

Das Problem ist die Kombination aus Inkrement und Zuweisung

Siehe hier:
http://c-faq.com/expr/seqpoints.html

Quote
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.

beeblebrox

Ich glaube bei Forumulierung 2 ist der Compiler nicht ganz sicher was du willst (may be undefined).

Also ob du meinst (index + 1) % anzwerte oder (index % anzwerte) + 1;


Ulli

Serenifly

Nein. Das ist nicht das Problem. Die Warnung kann man hier wörtlich nehmen. Das Ergebnis ist undefiniert. Da kommt eventuell raus was du erwartest, aber es kann auch was anderes sein

postmaster-ino

Hi

Aber warum KANN Da was Anderes raus kommen, als ich erwarte?
++/-- wird doch eh vorher ausgeführt, somit kann das Modulo nicht 'irgendwie' vorher angewendet werden.
Eine Klammerung
(++index)%anzwert;
bringt keine Besserung, die Warnung bleibt auch bei
(index++)%anzwert;
Einzig
(index + 1)%anzwert lässt die Warnung verstummen - wobei index++ <-> index +1 entsprechen sollte.
Spätestens durch die Klammerung sollte die Reihenfolge eindeutig sein, die Warnung interessiert Das aber nicht.

MfG

*Edit*
'Meine' Version spart noch ein paar Byte: (an einer Stelle geändert)
Code: [Select]
/* (x + 1) % max
Der Sketch verwendet 8578 Bytes (26%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 753 Bytes (36%) des dynamischen Speichers, 1295 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
 */

 /* ++x % max
Der Sketch verwendet 8496 Bytes (26%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 753 Bytes (36%) des dynamischen Speichers, 1295 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
  */
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

Serenifly

Quote
++/-- wird doch eh vorher ausgeführt
Denkt man natürlich leicht, aber die die Ausführungs-Reihenfolge ist nicht garantiert. Es gibt bestimmte Punkte bei denen eine Anweisung abgeschlossen ist und man ein definiertes Ergebnis hat. Dazwischen kann der Compiler was anderes draus machen. Logische Operatoren oder ein Strichpunkt z.B. schließen eine Sequenz ab

Quote
(index + 1)%anzwert
Da greift der andere Satz der Regel den ich nicht zitiert habe:
Quote
Furthermore, the prior value shall be accessed only to determine the value to be stored.
Das ist ein Lese-Zugriff und damit erlaubt

Derfips

Code: [Select]
++index = index % anzahl;

So kommt keine Warnung.


Gruß Fips
Meine Esp8266 & ESP32 Projekte => https://fipsok.de

zwieblum

Nur weil keine Warnung kommt heißt noch lange nicht dass das Ding tut was du willst.


Derfips

Meine Esp8266 & ESP32 Projekte => https://fipsok.de

postmaster-ino

Hi

Wow ... Das muß ich mir Mal auf der Zunge zergehen lassen ...
++index= | index wird um 1 erhöht, bevor die Zuweisung ausgeführt wird
index%anzahl | der erhöhte Index wird per Modulo mit anzahl verrechnet - ergibt 0...anzahl-1
Der berechnete Wert wird zugewiesen ... könnte klappen

MfG

PS: Das klappt - bin beeindruckt!
Code: [Select]

/* ++x=x % max; OHNE Warnung
Der Sketch verwendet 8496 Bytes (26%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 753 Bytes (36%) des dynamischen Speichers, 1295 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
 */

/* x=(x + 1) % max; OHNE Warnung
Der Sketch verwendet 8578 Bytes (26%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 753 Bytes (36%) des dynamischen Speichers, 1295 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
 */

 /* x=++x % max; MIT Warnung
Der Sketch verwendet 8496 Bytes (26%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 753 Bytes (36%) des dynamischen Speichers, 1295 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
  */

Die Version von DerFips macht, was Sie soll und braucht ebenfalls nur den Platz meiner Version - nur ohne Warnung.
... ist gekauft ...

PPS: Warum bei 'meiner' Version was Anderes heraus kommen können soll, erschließt sich mir zwar immer noch nicht - mit der Fips-Lösung (Wortspiel) kann ich aber sehr gut leben - sieht außerdem ungemein interessant aus, die Zeile, und regt zum drüber hinaus Nachdenken an.
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

combie

Quote
index = (index + 1) % anzWerte;

Selber nutze ich Ähnliches - meiner Meinung genau das Gleiche, wirft aber eine Warnung

index = ++index % anzWerte;
Macht, bzw. soll, NICHT das gleich machen.


> index = (index + 1) % anzWerte;
Read-Operation-Operation-Store


> index = ++index % anzWerte;
Read-Operation-Store-Operation-Store

Der nächstgelegene Sequence Point ist das jeweilige ;

Quote
OHNE Warnung
Wie schon gesagt wurde, der Compiler sieht nicht alle Probleme.
Auch sind Meldungen keine Pflicht im Standard.

Unsichtbar wird der Wahnsinn, wenn er genügend große Ausmaße angenommen hat.
(Berthold Brecht)

Doc_Arduino

Hallo,

wenn man ganz sicher gehen möchte macht man es einzeln.  ;)
Code: [Select]

index++;
index = index % anzWerte;
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

postmaster-ino

Hi

Vom verwendeten Platz ist Das mit ++index=index%anzWerte; identisch. (und mit ++index;index=index%anzWerte;)

MfG
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

combie

Eigentlich halt ich mich ja gerne aus solchen Diskussionen raus, denn sie sind meist unfruchtbar, so wie Geschmacks- und Glaubensfragen auch.



Wenn schon, dann denn schon:

Code: [Select]
index++;
index %= anzWerte;


Natürlich ist die  Größe gleich, auch bei einem SequencePoint Problem.
Nur eben die Anordnung/Reihenfolge der ASM Statements kann falsch sein, bzw. nicht so wie der Programmierer sich das wünscht.

Hier hat man das Konzept der Sequenzen zu akzeptieren, und entsprechend zu handeln.
Alternativen gibt es nicht.

Ein Grund für dieses Sequenz Konzept ist recht klar: "compiler reordering optimizations"
Je mehr Spielraum man dem Compiler einräumt, desto weitergehender kann er optimieren.
Das wird hier extensiv im verborgenen genutzt.
Verpflichtet den Programmierer aber zu etwas Disziplin.
Unsichtbar wird der Wahnsinn, wenn er genügend große Ausmaße angenommen hat.
(Berthold Brecht)

agmue

Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Go Up