Forum: Compiler & IDEs Warning: overflow in implicit constant conversion [-Woverflow]


von Thorsten (Gast)


Lesenswert?

Hallo, ich bekomme von meinem Compiler (XMC Dave) eine Warnung und bin 
mir nicht bewusst was diese bedeutet und ich die Warnung ignoieren kann 
oder mit dem Flag auch abschalten kann.

myheader.h:1824:12: warning: overflow in implicit constant conversion 
[-Woverflow]

Er muniert die Zeile bzw. das Zeichen ~
buf[4] &= ~(0xff << 0);

Was bedeutet die Warnung? Kann ich die Warnung ignoieren?
Was ist das Flag [-Woverflow]?

von Thorsten (Gast)


Lesenswert?

Entschuldigung. XMC Dave nutzt den ARM-GCC C Compiler.

von Amateur (Gast)


Lesenswert?

Den einen oder anderen (oder beide) würde schon die Definition von buf 
interessieren.

Muss aber nicht kund getan werden.

von lux. (Gast)


Lesenswert?

Ohne den restlichen Code gesehen zu haben (ernsthaft, wenn man mehr als 
raten sollte, braucht man den) würde ich vermuten, dass es daran liegt, 
dass Bitshift immer int (auf ARM 4Byte) retouniert, dass dann invertiert 
wird, was dazu führt, dass die ersten 3Byte High-Bits enthalten, die in 
buf nicht abgelegt werden können, da das vermutlich ein kleinerer 
Datentyp ist. Das Warning bekommst du dann deswegen, weil der Compiler 
weiß, dass hier Information abgeschnitten wird und aus irgendeinem Grund 
das Warning eingeschalten ist.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Ich nehme an, buf[] hat einen 8-Bit-Datentyp (uint8_t oder dergleichen).
Da stellt sich die Frage, was du mit der Anweisung überhaupt bezwecken
möchtest, denn sie ist äquivalent zu
1
buf[4] = 0;

Ansonsten sehe ich in dem Code kein Problem, denn das Ergebnis ist nach
Standard genau definiert. Du kannst die Warnung dadurch unterdrücken,
dass du 0xff durch 0xffu ersetzt.

Der Compiler scheint eine etwas seltsame Logik zu verfolgen, wann er
diese Warnung ausgibt und wann nicht:
1
  uint8_t u8;
2
3
  u8 &= 0x000; // keine Warnung
4
  u8 &= 0x0ff; // keine Warnung
5
  u8 &= 0x100; // Warnung
6
  u8 &= 0x101; // keine Warnung
7
  u8 &= 0x1ff; // keine Warnung
8
  u8 &= 0x200; // Warnung

Die Warnung scheint also immer dann ausgegeben zu werden, wenn der
rechte Operand nicht in 8 Bit darstellbar ist und zugleich die untersten
8 Bit alle 0 sind. Ich vermute, dass der Compiler erst nachschaut, ob
der Ausdruck optimiert werden kann (unterste 8 Bit alle 0) und danach
(in zwei verschiedenen Programmzweigen) den Überlauf prüft. Diese
Überlaufprüfung erfolgt in den zwei Programmzweigen wohl auf
unterschiedliche Weise.

: Bearbeitet durch Moderator
von Thorsten (Gast)


Lesenswert?

Hallo, entschuldigung das ich nicht den ganzen Code posten kann.
Buf ist ein Array aus Bytes bzw ein Zeiger auf das Array.

uint8_t buff_array[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t *buf;

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thorsten schrieb:
> Buf ist ein Array aus Bytes bzw ein Zeiger auf das Array.

Damit stellt sich allerdings in der Tat die Frage, was dein Code
bezweckt.  Den könntest du deutlich verständlicher schreiben:
1
buf[4] = 0;

von Thorsten (Gast)


Lesenswert?

Hallo, die Header Datei wird aus dem Script hier generiert:

http://www.infineonforums.com/threads/1166-Generating-C-Code-from-Vector-CANdb-.dbc-files

Ich denke er hat Standardmakros genommen und fuellt diese mit den 
Werten, ob nun das Byte 0x00 ist fragt er nicht ab, aber es hat mir die 
Arbeit mit dem DBC File sehr vereinfacht.

Ich war mir nun sehr unsicher, was die Warnung für eine Bedeutung hat.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wie geschrieben: wenn die Elemente von buf[] nur Bytes sind, dann
ist der Effekt von „buf[x] &= ~0xff“ eine verklausulierte Form,
statt gleich „buf[x] = 0“ zu schreiben: 0xFF bitweise negiert
(Operator „~“) ist nun einmal 0x00, und Null bleibt Null, egal wie
oft man sie (oder gar nicht) dann noch nach links schiebt.  Ein
Byte, verUNDet mit lauter Bits, die 0 sind, bekommt folglich den
Wert 0.

Wenn die Elemente von buf[] natürlich jemals größer als ein Byte sein
können, sieht die Sache anders aus.

: Bearbeitet durch Moderator
von Yalu X. (yalu) (Moderator)


Lesenswert?

Jörg, der Code ist von einem Awk-Skript generiert worden und kopiert
irgendwelche Werte an beliebige Bitpositionen innerhalb eines
Byte-Puffers. Ist die Bitposition ein Vielfaches von 8, kommen eben
solche – für das menschliche Auge seltsam anmutende – Konstrukte heraus.

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Ist die Bitposition ein Vielfaches von 8, kommen eben
> solche – für das menschliche Auge seltsam anmutende – Konstrukte heraus.

Wobei die Frage wäre, ob der Script diese Situation nicht erkennen
könnte und dann das Löschen der Bits durch Nullsetzen ersetzen kann
(besser: gleich das nächste ODER durch eine Zuweisung ersetzen).

Ich finde im Script aber nichts, was dieses ~(XX << Y) produzieren
würde.

von Luther B. (luther-blissett)


Lesenswert?

Jörg W. schrieb:
> 0xFF bitweise negiert
> (Operator „~“) ist nun einmal 0x00,

Nein, 0xff ist eine Konstante vom Type int und ist bitwise negiert nicht 
0 sondern je nachdem wie groß int ist 0xffffff00 (32 bit ints) oder 
0xff00 (16 bits ints). Auf dem XMC Dave dürfte es 0xffffff00 sein (wegen 
Cortex MCU).

Die problematische Zeile ist also äquivalent zu:

buf[4] &= (int)0xffffff00;

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Jörg W. schrieb:
> Wobei die Frage wäre, ob der Script diese Situation nicht erkennen
> könnte und dann das Löschen der Bits durch Nullsetzen ersetzen kann
> (besser: gleich das nächste ODER durch eine Zuweisung ersetzen).

Naja, wenn sich der Skriptschreiber sicher ist, dass der Compiler das
optimiert (der GCC zumindest tut das), kann er sich selber auf die faule
Haut legen ;-)

> Ich finde im Script aber nichts, was dieses ~(XX << Y) produzieren
> würde.

Es ist das Skript dbc2.awk in Verbindung mit dem Template
sig_setbuf.tpl, das in das Skript eingebunden wird.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Luther B. schrieb:
> Nein, 0xff ist eine Konstante vom Type int und ist bitwise negiert nicht
> 0

Du hast meine Vorbedingung weggelassen: „wenn buf[N] ein Byte ist“.

Allerdings scheint es in diesen Makros stets nur um Bytefolgen zu
gehen.

Sicherer wäre es natürlich, inline-Funktionen zu zimmern, die genau
diese Randbedingung dann explizit festhalten können.  Ein Makro kann
das nicht, weil seine Argumente nicht typisiert werden können.

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.