Hallo, ich habe hier einen Codeausschnitt aus meinem Programm angehängt, warum geht die Version mit *ptr++ nicht und mit *ptr = *ptr + 1 geht es ? Ich habe keine Erklärung dafür.
Schau dir mal die Operatorenrangfolge in C an.
1 | *ptr++; |
ist was Andres als
1 | (*ptr)++; |
Hauke M. schrieb: > warum geht die Version mit *ptr++ nicht und mit *ptr = *ptr + 1 geht es Ersteres inkrementiert ptr, das zweite inkrementiert das, worauf ptr zeigt. PS: Das Plenken sollte man lassen, damit das da nicht passiert: > ?
Hallo, ich hab das nochmal debugged, also *ptr++ incrementiert nicht den pointer!, es passiert einfach nichts.
Hauke M. schrieb: > ich hab das nochmal debugged, dann hast du schlecht debugged > also *ptr++ incrementiert nicht den > pointer! Doch, das tut es > es passiert einfach nichts. Es passiert mit Sicherheit, dass der Pointer nach dieser Operation nicht mehr auf int_cnt zeigt, sondern auf die nächste Speicherzelle.
Hauke M. schrieb: > ich hab das nochmal debugged, also *ptr++ incrementiert nicht den > pointer!, es passiert einfach nichts. Wird schon inkrementiert, aber da es in einer ISR passiert und der Pointer selbst nicht volatile ist merkst du das evtl. nicht. Was dir in der funktionierenden Version aber irgendwann auch passieren kann: dass der nicht wegoptimierbare Zugriff über den Pointer etwas anderes anzeigt, als der u.U. wegoptimierbare Zugriff auf die Variable. Und in ganz seltenen Fällen auch seltsame Aussreisser liefert. Aus http://www.mikrocontroller.net/articles/Interrupt#Interruptfeste_Programmierung "Ein ähnliches Problem entsteht bei Variablen, deren Größe die Wortbreite der Maschine übersteigt. Bei 8-Bit-Prozessoren wie AVR oder 8051 also bereits bei normalen "int" Variablen. Diese Variablen werden zwangsläufig byteweise verarbeitet. Wenn genau dazwischen ein Interrupt erfolgt, wird ein falscher Wert gelesen. Wenn beispielsweise eine Interrupt-Routine einen 16-Bit-Zähler verwendet und von 0x00FF auf 0x0100 hochzählt, dann kann das Hauptprogramm auch schon mal versehentlich die Werte 0x01FF oder 0x0000 lesen."
Hauke M. schrieb: > ich hab das nochmal debugged, also *ptr++ incrementiert nicht den > pointer!, es passiert einfach nichts. Der Compiler merkt sich erstmal nur, daß fürderhin ptr+1 benötigt wird. Für den aktuellen Ausdruck aber noch nicht, da ja post-increment. Wird aber ptr danach nicht mehr verwendet, dann muß er es auch nicht incrementieren. Das Increment wird also wegoptimiert. Und wird das *ptr nirgends zugewiesen, fällt auch das flach. Er hat also recht, wenn er garnichts macht. Peter
Karl heinz Buchegger schrieb: > Hauke M. schrieb: >> ich hab das nochmal debugged, > > dann hast du schlecht debugged > >> also *ptr++ incrementiert nicht den >> pointer! > > Doch, das tut es > >> es passiert einfach nichts. > > Es passiert mit Sicherheit, dass der Pointer nach dieser Operation nicht > mehr auf int_cnt zeigt, sondern auf die nächste Speicherzelle. Genauso ist es. Bei Operatoren mit gleicher Bindung gilt die Rechts-nach-Links-Regel (Rechtsassoziativität). Der Ausdruck *ptr++ liefert also lediglich den Inhalt der Speicherzelle, auf die ptr referenziert und inkrementiert ANSCHLIESSEND (nach Auswertung des Ausdrucks) den ptr. Die Anweisung *ptr++; allein macht so eben nichts, außer ptr zu inkrementieren, da der Wert des Ausdruck ja nicht genutzt wird. Bei (*ptr)++ wird die Bindungsreihenfolge geändert. Hier wird zuerst der Ausdruck *ptr ausgewertet, d.h. es handelt sich um den Inhalt der Speicherzelle, auf die ptr referenziert. Dieser Inhalt wird dann NACH Auswertung des Ausdrucks (z.B. Zuweisung) inkremetiert. Bei ++(*ptr) würde der Inhalt der Speicherzelle VOR Auswertung des Ausdrucks inkrementiert werden.
Hallo, ja das mit der Rechtsassoziativität hatte ich noch nicht verstanden, jetzt ist es klar! Nochmals vielen Dank für die Antworten, das Programm tut jetzt was es soll, dafür tauchen neue Sachen auf, aber da guck ich jeztt erstmal in den Threads nach.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.