Weil ich immer alles genau wissen mag:
Ausgangssituation:
OS : Slackware Linux
Compiler : SDCC 3.5.0
Zielhardware : STM8S103F3P6
Beim Spielen mit einer 4-stelligen 7-Segmentanzeige bekomme ich
Compilerwarnung:
overflow in implicit constant conversion
und weiß nicht warum!
Prototyp wie folgt deklariert:
void digit4_setall(uint8_t s3, uint8_t s2, uint8_t s1, uint8_t s0);
Ein Aufruf der Funktion mit:
digit4_setall(0xff, 0xff, ~(0x63), ~(0x39));
produziert die oben genannte Compilerwarnung.
digit4_setall(0xff, 0xff, 0x9c, 0xc6);
jedoch hingegen nicht.
Warum produziert eine bitweise Negation von 63h (Ergebnis = 9ch) beim
Aufruf die Warnung, wenn in der Deklaration doch steht, dass es ein
unsigned char ist )
Mir ist sehr bewusst, dass das höchstwertigste Bit bei der Negation
gesetzt wird, aber das ist sie bei der Konstanten 9ch aber auch (und bei
den beiden ffh davor sowieso) ?
Ralph S. schrieb:> Warum produziert eine bitweise Negation von 63h (Ergebnis = 9ch) beim> Aufruf die Warnung, wenn in der Deklaration doch steht, dass es ein> unsigned char ist )
Was meinst du mit "es"? 0x63 ist vom Typ int. ~0x63 ebenfalls. Wenn du
das als Parameter an eine Funktion übergibst, wird dieser Wert dann in
den Parametertyp der Funktion konvertiert. Und da muß dann ein int mit
dem Wert -100 in einen uint8_t konvertiert werden.
... unabhängig davon, dass ich dann jetzt eben die negierten Werte als
Konstante angebe (und das im Kommentar vermerke) hab ich der beiden
Beiträge
Rolf M. schrieb:> Und da muß dann ein int mit> dem Wert -100 in einen uint8_t konvertiert werden.Georg G. schrieb:> Zu uint8_t wird die Konstante erst ganz zum Schluss. Davor rechnet der> Compiler mit Integer, so ist es bei C als Standard definiert.
wegen das hier gemacht:
digit4_setall(0xff, 0xff, (uint8_t) ~(0x63), (uint8_t) ~(0x39));
Hier wird der Wert vor der Übergabe nach unsigned konvertiert wird
(allerdings ist mir das ein zu langer Ausdruck und deswegen schreib ich
gleich die negierten Werte hin )
Vielen Dank an Rolf und Georg
Ralph S. schrieb:> digit4_setall(0xff, 0xff, (uint8_t) ~(0x63), (uint8_t) ~(0x39));
...
> (allerdings ist mir das ein zu langer Ausdruck und deswegen schreib ich> gleich die negierten Werte hin )
Mir wäre das definitiv zu unleserlich.
Besser wartbar ist sowas:
Und noch hübscher bzw. universeller wird es, wenn die Umwandlung auf die
Segmentcodes in der Funktion verschwindet und man direkt eine Zahl oder
eine Zeichenkette übergeben kann.
Gruß
Friedrich
Friedrich schrieb:> Besser wartbar ist sowas:
Das aber löst nicht das Problem des Threadstarters, denn das Resultat
von
~(SEG_A + SEG_B + SEG_C + SEG_D + ...)
passt wieder nicht in einen uint8_t. Um das zu verhindern, müsste man
schon
(~(SEG_A + SEG_B + SEG_C + SEG_D + ...)) & 0xFF
verwenden.
Friedrich schrieb:> Ralph S. schrieb:>> digit4_setall(0xff, 0xff, (uint8_t) ~(0x63), (uint8_t) ~(0x39));> ...>> (allerdings ist mir das ein zu langer Ausdruck und deswegen schreib ich>> gleich die negierten Werte hin )>> Mir wäre das definitiv zu unleserlich.> Besser wartbar ist sowas:>
1
>#defineSEG_A0x01
2
>#defineSEG_B0x02
3
>#defineSEG_C0x04
4
>...
5
>#defineBLANK~(0)
6
>#defineNUM_0~(SEG_A+SEG_B+SEG_C+SEG_D+...)
7
>#defineNUM_1~(SEG_B+SEG_C)
8
>...
9
>digit4_setall(BLANK,BLANK,NUM_1,NUM_0);
10
>
>> Und noch hübscher bzw. universeller wird es, wenn die Umwandlung auf die> Segmentcodes in der Funktion verschwindet und man direkt eine Zahl oder> eine Zeichenkette übergeben kann.>> Gruß> Friedrich
Eine Funktion zum direkte setzen hatte ich ja sowieso schon, hier ging
es schlicht nur darum, einelne Segmente setzen zu können um Bspw. °C auf
der Anzeige zu sehen. Ansonsten gibt es schon eine
digit4_setdez(int value)
Funktion
Danke an alle noch mal....