Compiler Warnung"integer overflow in expression"verhindern

Gast #100292
Lesenswert?
• ▲
▼
GCC (Aus der aktuellen WINAVR Version) gibt mit bei der Zeile
largetemp = (capturedvalue*25)/(the_resistor*18432);
die oben genannte Warnung aus. largetemp und capturedvalue sind beide
vom Typ uint32_t, the_resistor ist 10. Mir ist klar, dass das
capturevalue*25 theoretisch die 32 Bit "sprengen" könnte, jedoch wird
capturevalue in der Praxis nicht so groß. Ich hab versucht dem Compiler
das mit einem
if (capturedvalue < 88473600) { //Maximaler Wert nach 24 Stunden
   largetemp = (capturedvalue*25)/(the_resistor*18432);
beizubringen. Aber das funktioniert nicht.
Wie bekomme ich die Warnung weg oder suche ich das Problem an der
falschen Stelle?
Gast #100294
Lesenswert?
• ▲
▼
Wenn ich das nach dem Verhalten des Programms urteile käme ich auf auf
den Gedanken dass es sich nur um einen 16Bit Typ handelt :-(
Nur wird uint32_t in der von WINAVR mitgelieferten inttypes.h als
typedef unsigned long uint32_t;
deklariert. Also long.
Gast #100295
Lesenswert?
• ▲
▼
Die Warnung ist weg, soblad ich
#define the_resistor 10
largetemp = (capturedvalue*25)/(18432*the_resistor);
durch
largetemp = (capturedvalue*25)/(184320);
ersetze. Interresanterweise spare ich 16 Byte Flash wenn ich das
wiederum in
largetemp = (capturedvalue*25);
largetemp /= 184320;
ändere.
Jetzt tut das Programm jedenfalls auch das, was es soll. Nur wieso war
das vorher nicht der Fall? :-|
Gast #100296
Lesenswert?
• ▲
▼
Hi!

Ich denke das Problem kommt daher, dass bei 18432*the_resistor
der int überläuft. Hier nimmt der Compiler scheinbar einen
16-Bit int als Datentyp an. 18432 passt noch in einen 16-bit int,
aber 184320 nicht mehr...
Wenn Du hingegen 184320 als Konstante direkt angibst, nimmt der
Compiler wohl automatisch einen 32-Bit int.
Dein erster Ansatz müsste also mit
largetemp =
(capturedvalue*25)/((uint32_t)the_resistor*(uint32_t)18432);
auch funktionieren...

Bye
  Daniel Jelkmann
Gast #100297
Lesenswert?
• ▲
▼
Die Berechnung von Ausdrücken erfolgt laut Standard im Datentyp `int',
sofern nicht einer der Operanden etwas anderes besagt (entweder bei
einer Variablen durch deren Datentyp, oder durch typecast).

Konstanten sind laut Standard implizit `int', es sei denn, sie können
damit nicht mehr dargestellt werden, dann sind sie implizit `long'.
Damit wird in letzterem Fall auch der gesamte Ausdruck `long'.

Besser ist es natürlich, passende typecasts vorzusehen bzw. Konstanten
auch gleich passend (mit Suffix `L' bzw. `UL') zu versehen wenn man
weiß, daß sie im Bereich des normalen [unsigned] int nicht mehr
darstellbar sind.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren