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]?
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.
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_tu8;
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.
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;
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:
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.
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.
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.
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.
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;
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.
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.