mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SDCC: overflow in implicit constant conversion


Autor: Ralph S. (jjflash)
Datum:

Bewertung
0 lesenswert
nicht 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) ?

Autor: Georg G. (df2au)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu uint8_t wird die Konstante erst ganz zum Schluss. Davor rechnet der 
Compiler mit Integer, so ist es bei C als Standard definiert.

Autor: Rolf M. (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralph S. schrieb:
> digit4_setall(0xff, 0xff, ~(0x63), ~(0x39));

Mach stattdessen folgendes:
digit4_setall(0xff, 0xff, (0x63^0xff), (0x39^0xff));

Autor: Ralph S. (jjflash)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Friedrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#define SEG_A      0x01
#define SEG_B      0x02
#define SEG_C      0x04
...
#define BLANK      ~(0)
#define NUM_0      ~(SEG_A + SEG_B + SEG_C + SEG_D + ...)
#define NUM_1      ~(SEG_B + SEG_C)
...
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

Autor: Rufus Τ. F. (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: neuer PIC Freund (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
digitsetall.c:
#include <stdint.h>

void digit4_setall(uint8_t s3, uint8_t s2, uint8_t s1, uint8_t s0)
{
  volatile uint8_t x = 0;
  if (s3 == s2)
    x += 1;
  if (s0 != s1)
    x += 3;
}

void main(void)
{
  digit4_setall(0xff, 0xff, ~(0x63), ~(0x39));
}

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

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

Nö. Nur Warnungen. Allerdings ist der sdcc taufrisch übersetzt.

Autor: Ralph S. (jjflash)
Datum:

Bewertung
0 lesenswert
nicht 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:
>
> #define SEG_A      0x01
> #define SEG_B      0x02
> #define SEG_C      0x04
> ...
> #define BLANK      ~(0)
> #define NUM_0      ~(SEG_A + SEG_B + SEG_C + SEG_D + ...)
> #define NUM_1      ~(SEG_B + SEG_C)
> ...
> 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

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

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.