Forum: Compiler & IDEs Integer Sättigung


von Ingo (Gast)


Lesenswert?

Hallo,

ich habe einen vermeintlichen Fehler in meinem C Programm (CoIDE) unter 
einem STM32F405 gefunden, der sich aber nicht auswirkt. Jetzt ist die 
Frage, ob evtl. an der DSP-Fähigkeit des Controllers liegt und sich 
daher alles noch normal verhält.

Normalerweise würde ich hier
1
  uint32_t MSDelayCounter = 0;
2
  /* Wartezeit */
3
  if ( MSDelayCounter-- );
erwarten, dass die Variable MSDelayCounter einen Underflow hat, sodass 
sie wieder bei 2^32 - 1 anfängt, wenn sie auf 0 steht.
Tut sie aber nicht. Auf einem AVR führt dieser Code zu einem Underflow, 
auf dem STM32F4xx unter GCC nicht.

Auf einem AVR ist folgendes nötig:
1
  uint32_t MSDelayCounter = 0;
2
  /* Wartezeit */
3
  if ( MSDelayCounter ) MSDelayCounter--;

Liegt das nun am DSP der Controllers?




Ingo

von Karl H. (kbuchegg)


Lesenswert?

Ingo schrieb:

> Tut sie aber nicht.

Was tut sie statt dessen?
Da es sich hier um eine unsigned Variable handelt, ist an und für sich 
aus dem C Standard heraus genau definiert, was hier zu geschehen hat. Da 
hat ein Compiler keine Freiheiten. Der C Standard sagt eindeutig, dass 
es hier zu einem Wrap Around Effekt kommt, so wie du das erwartest.

von Ingo (Gast)


Lesenswert?

Karl Heinz schrieb:
> Was tut sie statt dessen?

Sie bleibt 0

von (prx) A. K. (prx)


Lesenswert?

Dann solltest du das mal als nachvollziehbares Beispiel posten. 
Vorzugsweise mitsamt des generierten Codes als Assembler-Listing.

von Peter D. (peda)


Lesenswert?

Ingo schrieb:
> if ( MSDelayCounter-- );

Ein If mit leerer Anweisung, wer schreibt denn sowas?
Da ist bestimmt noch anderes nicht koscher in Deinem Code.

Ingo schrieb:
> Tut sie aber nicht.

Woher weißt Du das?
Du mußt schon den Kontext dazu zeigen.

von innerand i. (innerand)


Lesenswert?

Ingo schrieb:

>
1
>   if ( MSDelayCounter-- );
2
>

Wer schreibt denn bitte solchen Code? Ist ja furchtbar...
Um raus zu finden was das macht muss ich erstmal den Compiler anwerfen, 
und da wird wohl bei jedem Compiler was anderes raus fallen.

von (prx) A. K. (prx)


Lesenswert?

innerand innerand schrieb:
> Wer schreibt denn bitte solchen Code? Ist ja furchtbar...

Zwar furchtbar, aber eindeutig definiert. Sowas kommt raus, wenn man dem 
Forum zuliebe den Code eindampft.

von Ingo (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Ein If mit leerer Anweisung, wer schreibt denn sowas?
Das ist ja der Fehler. Da er sich aber nicht ausgewirkt hat lief es so.
1
volatile int MSDelayCounter;
1
/* Delayroutine */
2
void MyDelayMS( int DelayInMS )
3
{
4
  MSDelayCounter = DelayInMS * SYSTICK_IN_HZ / 1000;
5
  while (MSDelayCounter);
6
}

im Timeraufruf
1
if ( MSDelayCounter-- );

und es funktioniert wie es soll...

Ich bereite den alten Code gerade auf, habe aber das System grad nicht 
zur Hand und bin darüber gestolpert. Ich bin der Meinung ich habe es 
damals im Debugger so gehabt, dass es nicht negativ wird und keinen 
Unterflow gibt.

Die erste Info mit dem uint32_t war falsch, sorry, es handelt sich um 
einen normalen int...


Ingo

von (prx) A. K. (prx)


Lesenswert?

Ingo schrieb:
> if ( MSDelayCounter-- );

Das ist nun wirklich Unfug. Weil kein Unterschied zu
   MSDelayCounter--;

von (prx) A. K. (prx)


Lesenswert?

Ingo schrieb:
> Die erste Info mit dem uint32_t war falsch, sorry, es handelt sich um
> einen normalen int...

Aha! Bei "int" sind Über/Unterlauf undefiniert und wenn der Compiler das 
spitz kriegt, dann gibts mitunter höchst unerwartete Ergebnisse, weil 
dann jeder vermeintliche Unfug erlaubt ist.

von (prx) A. K. (prx)


Lesenswert?

Ingo schrieb:
>   if ( MSDelayCounter ) MSDelayCounter--;

So ist es richtig.

von Ingo (Gast)


Lesenswert?

A. K. schrieb:
> So ist es richtig.
Ich habs nun so...

von Peter D. (peda)


Lesenswert?

Ingo schrieb:
> uint32_t MSDelayCounter = 0;

Ingo schrieb:
> volatile int MSDelayCounter;

Was denn nun?
Entscheide Dich mal für einen Typ.

Beim 32Bit-Boliden brauchst Du keinen Unterlauftest, weil das MyDelayMS 
oft genug vorbeikommt, um jede Änderung mitzukriegen.

Beim 8Bit-AVR mußt Du aber das 32Bit-Lesen atomar kapseln. Außerdem kann 
ein anderer Interrupt so lange verzögern, daß der Timer schon 2 Schritte 
weiter gezählt hat.

von (prx) A. K. (prx)


Lesenswert?

Peter Dannegger schrieb:
> Beim 32Bit-Boliden brauchst Du keinen Unterlauftest, weil das MyDelayMS
> oft genug vorbeikommt, um jede Änderung mitzukriegen.

Ich würde es drin lassen. Falltüren dieser Art müssen nicht sein. So 
teuer ist das nicht.

von Peter D. (peda)


Lesenswert?

Es war nur der Erklärungsversuch, warum ARM-C/AVR-C sich scheinbar 
unterschiedlich verhalten sollten.

Aber da der wirkliche Code nun schlußendlich doch mit (signed) int lief, 
ist all das hinfällig geworden, da nicht definiert.

Ich finds immer wieder nervig, wenn völlig anderer ungetesteter Code 
gepostet wird und dann die wildesten Behauptungen darüber aufgestellt 
werden.

A. K. schrieb:
> Ich würde es drin lassen.

Bei (signed) int musses sogar drin bleiben, damit man nicht in 
undefiniert rein rennt.

von Dr. Sommer (Gast)


Lesenswert?

Ingo schrieb:
> ob evtl. an der DSP-Fähigkeit des Controllers liegt und sich
> daher alles noch normal verhält.
Nein, für die brauchts spezielle Instruktionen (zB "QSUB"), die man 
durch Inline-Assembler oder durch Verwendung der entsprechenden 
CMSIS-DSP-Library nutzen kann.

von Mark B. (markbrandis)


Lesenswert?

Peter Dannegger schrieb:
> Ich finds immer wieder nervig, wenn völlig anderer ungetesteter Code
> gepostet wird und dann die wildesten Behauptungen darüber aufgestellt
> werden.

Full ACK. Das nervt echt wie Sau.

von Ingo (Gast)


Lesenswert?

Mehr als entschuldigen für die falschen Infos zu Beginn kann ich nicht. 
Ich hoffe ihr könnt vor lauter Wut heute Nacht schlafen ?


Ingo

von Mark B. (markbrandis)


Lesenswert?

Ingo schrieb:
> Mehr als entschuldigen für die falschen Infos zu Beginn kann ich nicht.
> Ich hoffe ihr könnt vor lauter Wut heute Nacht schlafen

Das Problem ist, dass sowas hier andauernd passiert. Leute posten ihren 
Code gar nicht, oder halb, oder nicht den Code der das Problem aufweist. 
Das macht keinen Spaß :-(

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
Noch kein Account? Hier anmelden.