mikrocontroller.net

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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Ralph S. (jjflash)


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) ?

von Georg G. (df2au)


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.

von Rolf M. (rmagnus)


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.

von chris (Gast)


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));

von Ralph S. (jjflash)


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

von Friedrich (Gast)


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

von Rufus Τ. F. (rufus) (Moderator) Benutzerseite


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.

von neuer PIC Freund (Gast)


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.

von Ralph S. (jjflash)


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.