SDCC: overflow in implicit constant conversion

OP #4689605
Lesenswert?

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) ?
#4689621
Lesenswert?

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.
OP #4689647
Lesenswert?

... 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
Gast #4689660
Lesenswert?

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
#define SEG_A      0x01
2
#define SEG_B      0x02
3
#define SEG_C      0x04
4
...
5
#define BLANK      ~(0)
6
#define NUM_0      ~(SEG_A + SEG_B + SEG_C + SEG_D + ...)
7
#define NUM_1      ~(SEG_B + SEG_C)
8
...
9
digit4_setall( BLANK, BLANK, NUM_1, NUM_0);

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
Gast #4689739
Lesenswert?

digitsetall.c:
1
#include <stdint.h>
2

3
void digit4_setall(uint8_t s3, uint8_t s2, uint8_t s1, uint8_t s0)
4
{
5
  volatile uint8_t x = 0;
6
  if (s3 == s2)
7
    x += 1;
8
  if (s0 != s1)
9
    x += 3;
10
}
11

12
void main(void)
13
{
14
  digit4_setall(0xff, 0xff, ~(0x63), ~(0x39));
15
}

Welcher Compiler?
1
$ sdcc --version
2
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.6.3 #9727 (Linux)
3
published under GNU General Public License (GPL)

Noch Fehler?
1
$ sdcc -mstm8 digitsetall.c 
2
digitsetall.c:20: warning 158: overflow in implicit constant conversion
3
digitsetall.c:20: warning 158: overflow in implicit constant conversion

Nö. Nur Warnungen. Allerdings ist der sdcc taufrisch übersetzt.
OP #4689756
Lesenswert?

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
> #define SEG_A      0x01
2
> #define SEG_B      0x02
3
> #define SEG_C      0x04
4
> ...
5
> #define BLANK      ~(0)
6
> #define NUM_0      ~(SEG_A + SEG_B + SEG_C + SEG_D + ...)
7
> #define NUM_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....

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren