Hallo, ich will einen Überlauf in C bewusst einsetzen, und habe mich gefragt, was passiert, wenn ich ein uint8_t i = 0xff inkrementiere. Die geht doch dann auf 0 und sonst nichts, oder? Hintergrund: Habe einen Moving-Average-Filter und schalte zwischen mehreren AD-Ports um. Da dies in der Interrupt-Schleife geschieht ist der erste AD-Wert noch vom "alten" Port und daher für den neuen MA uninteressant und soll verworfen werden. Um dies festzustellen, nehme ich die Zählervariable, d.h. i. Dies ist die Anzahl der bisherigen Samples des Filters, die nach dem initialisieren hochzählt bis die Filterlänge erreicht ist. Anschließend arbeitet der Filter rekursiv. Dient primär dem Einsparen unnötiger Variablen.
Regler schrieb: > Hallo, > > ich will einen Überlauf in C bewusst einsetzen, und habe mich gefragt, > was passiert, wenn ich ein uint8_t i = 0xff inkrementiere. Die geht doch > dann auf 0 und sonst nichts, oder? Ja, und es wird das Überlauf Flag gesetzt.
Antwort schrieb: > und es wird das Überlauf Flag gesetzt. Okay?! Das könnte ich abfragen. Wo eigentlich? Wenn ich's lasse, passiert nichts weiter, oder? Oder gibts noch weitere Konsequenzen, wie etwa das Beschreiben einer anderen, genauer der nächsten Speicherstelle. Wie gesagt: Mir ist zu diesem Zeitpunkt völlig bewusst, dass ein Überlauf passiert.
Schau im Datenblatt deines Controllers nach dem Carry-Flag (ich weiß nicht welchen du verwendest)
>>Antwort schrieb: >> und es wird das Überlauf Flag gesetzt. >Okay?! Das könnte ich abfragen. Wo eigentlich? Die Antwort von "Antwort" ist so nicht richtig. Wenn wir von C Programmen reden, dann gibt es dort ein Überlauf Flag nicht. Nirgendwo ist sowas definiert. Also kann man das auch nicht abfragen. Ein anderer Punkt ist natürlich, das das C Programm ja in ein Assembler-Programm umgesetzt wird und auf einer konkreten CPU läuft. Deswegen und weil die viele CPUs bei einem Inkrement auch ein Überlauf-Flag setzen, ist es, insbesondere wenn man in ein C Programm Assemblerbefehle inkorporieren kann, zwar möglich, diese Flag abzufragen, aber es ist nirgendwo in der C-Sprachbeschreibung definiert, das und auf welche Weise ein Inkrement in Assembler umgesetzt wird, welcher Befehl, welches Register etc. dafür verwendet wird und das mischen von C mit Assemblercode ist auch nicht Standard sondern z.B. eine Besonderheit von GCC und anderen. Da aber die Hauptfrage ja war: "Die geht doch dann auf 0 und sonst nichts, oder?" und man diese mit Ja beantworten muss, spielt das alles garkeine Rolle.
> ich will einen Überlauf in C bewusst einsetzen
Laut C-Standart ist das Ergebnis undefiniert.
Einen AVR (Genauer einen ATtiny26). Programmiere in C und bin mir nicht ganz bewusst, ob der Missbrauch eines Überlaufs Konsequenzen hat. Was passiert mit dem Carry-Flag wenn es nicht für eine bestimmte Operation (z.B. eine 16-Bit Op) verwendet wird. Muss ich das selbst händisch zurücksetzen (da der Compiler das wahrscheinlich nicht automatisch macht!?) oder passiert das vollautomatisch, wenn es nicht abgefragt und eine neue Op ausgeführt wird?
C-Experte schrieb: >> ich will einen Überlauf in C bewusst einsetzen > > Laut C-Standart ist das Ergebnis undefiniert. Das ist Unsinn. Der C Standar>>>D<<< definiert den Überlauf einer unsigned Variable ziemlich exakt.
Regler schrieb: > Einen AVR (Genauer einen ATtiny26). > Programmiere in C und bin mir nicht ganz bewusst, ob der Missbrauch > eines Überlaufs Konsequenzen hat. Was passiert mit dem Carry-Flag wenn > es nicht für eine bestimmte Operation (z.B. eine 16-Bit Op) verwendet > wird. Muss ich das selbst händisch zurücksetzen (da der Compiler das > wahrscheinlich nicht automatisch macht!?) oder passiert das > vollautomatisch, wenn es nicht abgefragt und eine neue Op ausgeführt > wird? Der Compiler kümmert sich um das carry flag wo nötig.
C-Experte schrieb: > Laut C-Standart ist das Ergebnis undefiniert. Und aus der Sicht von AVR-GCC? Huch schrieb: > Da aber die Hauptfrage ja war: "Die geht doch dann auf 0 und sonst > nichts, oder?" und man diese mit Ja beantworten muss, spielt das alles > garkeine Rolle. Alles klar, d.h. ich brauch keine bösen Bugs durch diesen "Missbrauch" befürchten (z.B einen Fehler in der nächsten 16-Bit Op.)?
Huch schrieb: > Die Antwort von "Antwort" ist so nicht richtig. Wenn wir von C > Programmen reden, dann gibt es dort ein Überlauf Flag nicht. Nirgendwo > ist sowas definiert. Also kann man das auch nicht abfragen. > > Ein anderer Punkt ist natürlich, das das C Programm ja in ein > Assembler-Programm umgesetzt wird und auf einer konkreten CPU läuft. > Deswegen und weil die viele CPUs bei einem Inkrement auch ein > Überlauf-Flag setzen, ist es, insbesondere wenn man in ein C Programm > Assemblerbefehle inkorporieren kann, zwar möglich, diese Flag > abzufragen, Speziell beim AVR kann man doch SREG abfragen. Das geht auch in C ohne Assembler-Befehle.
Michael Buesch schrieb: > C-Experte schrieb: >>> ich will einen Überlauf in C bewusst einsetzen >> >> Laut C-Standart ist das Ergebnis undefiniert. > > Das ist Unsinn. Der C Standar>>>D<<< definiert den Überlauf einer > unsigned Variable ziemlich exakt. An sowas kann ich mich auch erinnern irgendwann irgendwo gelesen zu haben. Man beachte, vorzeichenlos!
Michael Buesch schrieb: > Der Compiler kümmert sich um das carry flag wo nötig. Und da es eine 8-bit Variable ist, die inkrementiert wird, macht er das in dem Fall nicht, oder? Daher: > Muss ich das selbst händisch zurücksetzen (da der Compiler das > wahrscheinlich nicht automatisch macht!?) oder passiert das > vollautomatisch, wenn es nicht abgefragt und eine neue Op ausgeführt > wird? und: Muss ich einen bösen Bug im Programmablauf befürchten?
Markus schrieb: > Speziell beim AVR kann man doch SREG abfragen. Das geht auch in C ohne > Assembler-Befehle. Ist mir völlig klar. Aber: was soll das bringen? Ich weiß ja dass das Carry-Flag gesetzt sein wird. Muss ich es händisch zurücksetzen ist die goldene Frage! Oder anders: Will nur wissen, was mit dem Carry-Flag passiert, wenn es NICHT abgefragt wird.
Markus schrieb: > Speziell beim AVR kann man doch SREG abfragen. Das geht auch in C ohne > Assembler-Befehle. Das wird nur durch Zufall funktionieren, wenn überhaupt. Beispiel: a += 1 b = SREG Niemand garantiert dir, dass zur zweiten Zeile das carry flag noch den Zustand von der "add" instruktion hat. Nein, auch nicht wenn interrupts abgeschaltet sind. Genauer gesagt garantiert auch niemand, dass überhaupt eine add instruktion verwendet wird. Der compiler könnte möglicherweise auch das ganze Konstrukt auflösen, weil vielleicht alles zur Compilezeit bekannt ist oder sonst eine andere beliebige Optimierung. Und dann kommt bei dem SREG nur nur zufälliges Gemüse raus. Die einzige Möglichkeit ist es sowohl das add als auch das lesen des carry bits im inline-assembly auszuführen.
Regler schrieb: > Muss ich es händisch zurücksetzen ist die goldene Frage! Oder anders: > Will nur wissen, was mit dem Carry-Flag passiert, wenn es NICHT > abgefragt wird. Nichts. Du musst gar nichts machen. Der Überlauf einer unsigned Variable ist vollständig in C definiert und es passiert garantiert nichts Unvorhergesehenes. Da es in C kein carry flag gibt, muss man es natürlich auch nicht zurücksetzen.
Habs gerade gefunden, hier: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Vergleiche Zitat: Überläufe, die durch Inkrementieren oder Dekrementieren (INC/DEC) erzeugt werden, beeinflussen das Carry-Flag jedoch nicht. Damit hat sich die Antwort gefunden, da ich jetzt einfach mal davon ausgehe, dass der Compiler den ++-Operator nach INC übersetzt!
Regler schrieb: > Damit hat sich die Antwort gefunden, da ich jetzt einfach mal davon > ausgehe, dass der Compiler den ++-Operator nach INC übersetzt! Da würde ich nicht von ausgehen. Es spielt aber auch keine Rolle wie er es übersetzt. Die CPU Flags spielen in C keine Rolle und werden vom Compiler verwaltet (außer Spezialflags wie I, die der Compiler nicht antastet).
Regler schrieb: > Michael Buesch schrieb: >> Da würde ich nicht von ausgehen. > > So abwegig? Nein, aber er ergibt keinen sinn von C Ausdrücken auf generierten Assemblycode zu schließen. Ich garantiere dir, dass ich zu jeder Annahme einen Compiler(version) finde dem diese Ahnahme egal ist und es anders macht. ;)
> Ich garantiere dir, dass ich zu jeder Annahme einen Compiler(version) > finde dem diese Ahnahme egal ist und es anders macht. ;) Das ist ja das Fiese! ;)
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.