Forum: Compiler & IDEs Compiler Warnung"integer overflow in expression"verhindern


von Malte Marwedel (Gast)


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?

von Alex (Gast)


Lesenswert?

Meiner Meinung nach hat ein normaler int 16bit, du müsstest ihn schon
als long deklarieren, damit es überhaupt erstmal 32bit werden.

von Malte Marwedel (Gast)


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.

von Malte Marwedel (Gast)


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? :-|

von Daniel Jelkmann (Gast)


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

von Jörg Wunsch (Gast)


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.

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.