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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.