hallo
Ich verstehe das Problem oben nicht.
Wenn ich
ZEROdec und alle folgenden digitArray hinzufuege, taucht die Meldung
implicit conversion from int to uint8_t
Wenn ich den Typen zu uint8_t caste passt es, aber warum taucht der
Fehler bei normal ZERO ONE etc Definitionen nicht auf? Siehe Bild oben
Danke
Schueler schrieb:> Ich verstehe das Problem oben nicht.
Ich verstehe dein Problem auch nicht, aber eines sehe ich bei deinen
Bildern: du pfriemelst mir viel zu sehr mit ominösen Bezeichnern herum,
deren Sinn durch Lesen deiner Quellen nicht erfaßbar ist. Also wozu
sollen denn sowas wie ZEROdec und ZERO dienen? Und was willst du mit
diesen Definitionen dann bewirken?
Fehlt es dir vielleicht an der Kenntnis geeigneter Algorithmen, die
solche Flut an ominösen Definitionen überflüssig machen würden?
Mein Rat: schreibe einen verständlicheren und lesbareren Quellcode als
bisher. Das wird dann auch dir selbst zugute kommen, wenn du nach einem
Jahr oder so nochmal in diese Quelle hineinschauen mußt.
W.S.
ZEROdec ist gleich -192, was außerhalb des Wertebereichs von uint8_t
liegt, somit ist die Warnung gerechtfertigt.
ZERO ist gleich -64, was ebenfalls außerhalb des Wertebereichs von
uint8_t liegt, so dass der Compiler eigentlich auch hier warnen müsste.
In diesem Fall drückt er aber ein Auge zu, da -64 im Gegensatz zu -192
immerhin in ein int8_t passt und es erfahrungsgemäß viele Programmierer
mit der Unterscheidung zwischen signed und unsigned Typen nicht so genau
nehmen. Gehörst du nicht zu diesen Schlampern, kannst du (zumindest beim
GCC) die Warnung mit -Wconversion auch für diesen Fall aktivieren.
Ich würde einmal versuchen den Kommentar hinter ZEROdec von // 41 auf
/* 41 */ zu ändern.
Grund könnte sein: #define tauscht den Text hinter dem ersten Wort gegen
das erste Wort
Ich hatte schon ein ähnliches Problem. Kann natürlich von der
Implementierung des Precompilers abhängig sein.
W.S. schrieb:> Fehlt es dir vielleicht an der Kenntnis geeigneter Algorithmen, die> solche Flut an ominösen Definitionen überflüssig machen würden?
Das sind die Bitmuster für eine Siebensegmentanzeige. Die lassen sich
kaum algorithmisch berechnen. Allenfalls die <ZIFFER>dec-Werte für die
Anzeige mit Dezimalpunkt könnten aus den <ZIFFER>-Werten durch verodern
mit 0x80 (bzw. durch verunden mit ~0x80 in der invertieren Darstellung)
berechnet werden.
GEKU schrieb:> Ich würde einmal versuchen den Kommentar hinter ZEROdec von // 41 auf> /* 41 */ zu ändern.>> Grund könnte sein: #define tauscht den Text hinter dem ersten Wort gegen> das erste Wort>> Ich hatte schon ein ähnliches Problem. Kann natürlich von der> Implementierung des Precompilers abhängig sein.
Das wäre ein Bug des Compilers bzw. des Präprozessors, der in diesem
Fall aber nicht zu Typwarnungen, sondern zu Syntaxfehlern führen würde.
Yalu X. schrieb:> Das wäre ein Bug des Compilers bzw. des Präprozessors
Sehe ich auch so. Man müsste sich das Ergebnis des Präprozessors
ansehen.
Ich hatte folgendes Problem:
1
#define ANTON 4 // Kommentar
1
if(x>ANTON)
if erhielt die Fehlermeldung, dass die schließende Klammer fehlt
Das Zwischenergebnis des Präprozessors zeigte:
1
if(x>4// Kommentar)
erst mit:
1
#define ANTON 4 /* Kommentar */
war das Problem beseitigt.
Das Zwischenergebnis des Präprozessors war:
Dirk B. schrieb:> Hast du schon mal versucht, die Literale als unsigned zu definieren?>> z.B:: ~0x3fU
Das hat den Wert 4294967232 und passt erst recht nicht in uint8_t.
Besser (wenn man auf den Cast verzichten möchte):
1
#define ZEROdec (0xBF ^ 0xFF)
2
#define ZERO (0x3F ^ 0xFF)
3
// usw.
Damit werden nur die letzten 8 Bits, auf die es ja schließlich ankommt,
invertiert, und das Ergebnis liegt immer im uint8_t-konformen Bereich
von 0 bis 255.
GEKU schrieb:> GEKU schrieb:>> if (x > 4 // Kommentar)>> Auch der C-Text Präprozessors auf dieser Seite erkennt die Klammern> nicht!> Der Kommentar wird grau dargestellt.
Das ist nicht, wie das funktioniert...
Die klammer ist in dem Beispiel teil des Kommentars. Ein Kompiler sollte
Kommentare durch Leerzeichen ersetzen, bevor die Macros ersetzt werden,
wäre da also ein Makro, könnte dieses niemals einen Kommentar
beinhalten, welcher wie im Beispiel die Klammer auskommentiert.
Der springende punkt ist aber, dass Kommentare vor den Makros ersetzt
werden. Beispiel:
1
#define X int // Kommentar
2
XY;
Wird zu:
1
#define X int
2
XY;
Wird zu:
1
intY;
Siehe den Abschnitt Phasen deines verlinkten Wikipedia Artikels:
https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor#Phasen
Eine Situation "int // Kommentar Y;" kann in dem Fall also bei einem
echten C Compiler gar nie auftreten.
DPA schrieb:> Siehe den Abschnitt Phasen deines verlinkten Wikipedia Artikels:> https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor#Phasen
Der Link hat mich überzeugt.
Es muss ein Bug des Compilers gewesen sein.
Danke für die Info!
Jetzt kann ich beruhigt wieder auf // zurückkehren.
Wau vielen Dank
Ich werde morgen die verschiedenen Ratschlaege umsetzen und sehen was
hilft.
Yalu X. schrieb:> Allenfalls die <ZIFFER>dec-Werte für die> Anzeige mit Dezimalpunkt könnten aus den <ZIFFER>-Werten durch verodern> mit 0x80 (bzw. durch verunden mit ~0x80 in der invertieren Darstellung)> berechnet werden.
Zuvor hatte ich es auch so
zB. #define ZEROdec ~(0x3F | 0x80)
aber dann dachte ich dass das der Fehler sei und hatte es moeglichst
glei wie ZERO definiert und direkt zum high byte 8 hinzugezaehlt.
Schueler schrieb:> Ich verstehe das Problem oben nicht.
Und ich verstehe nicht, wie man Quelltext als schiefes Bild posten kann,
statt in der naheliegendsten Form als *.c-File.
GEKU schrieb:> DPA schrieb:>> Siehe den Abschnitt Phasen deines verlinkten Wikipedia Artikels:>> https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor#Phasen>> Der Link hat mich überzeugt.> Es muss ein Bug des Compilers gewesen sein.
Jein.
> Jetzt kann ich beruhigt wieder auf // zurückkehren.
Wenn du das tust, dann stell den Compiler aber auch auf C99 ein. Denn
Kommentare mit zwei Slashes sind erst mit C99 offiziell in den
C-Standard aufgenommen worden (nachdem sie in C++ eingeführt wurden und
die meisten Implementationen des Präprozessors ohnehin C und C++
beherrschten).
Es ist gut möglich, daß dein "kaputter" Compiler sich einfach nur an
einen älteren Standard gehalten hat.
Yalu X. schrieb:> Dirk B. schrieb:> Hast du schon mal versucht, die Literale als unsigned zu definieren?> z.B:: ~0x3fU>> Das hat den Wert 4294967232 und passt erst recht nicht in uint8_t.>> Besser (wenn man auf den Cast verzichten möchte):#define ZEROdec (0xBF ^> 0xFF)> #define ZERO (0x3F ^ 0xFF)> // usw.>> Damit werden nur die letzten 8 Bits, auf die es ja schließlich ankommt,> invertiert, und das Ergebnis liegt immer im uint8_t-konformen Bereich> von 0 bis 255.
das hat funktioniert ?
Warum aber genau? Im Endeffekt sind die Werte dahinter ja gleich?!
Schueler schrieb:> Yalu X. schrieb:>> Damit werden nur die letzten 8 Bits, auf die es ja schließlich ankommt,> invertiert, und das Ergebnis liegt immer im uint8_t-konformen Bereich> von 0 bis 255.>
Aha darum..
Weil Wert ja normal ein int ist und ich nur 1 Byte davon manipuliere.
Schueler schrieb:>IMG_20190503_130400.jpg
Was soll der Scheiß? Nicht nur, daß deine Screenshots mit der Kamera
unter aller Sau und voller Interferenzen sind, macht man sowas schlicht!
Sende den originalen Quelltext als Anhang! Siehe Netiquette. Ich
hoffe, daß ein "Schueler" noch lernfähig ist.
Schueler schrieb:> Yalu X. schrieb:>> Dirk B. schrieb:>> ...>> z.B:: ~0x3fU>> ...>> #define ZERO (0x3F ^ 0xFF)>> das hat funktioniert ?> Warum aber genau? Im Endeffekt sind die Werte dahinter ja gleich?!
Nein, überhaupt nicht. Beachte, dass die Operationen 32-Bit-breit
ausgeführt werden.
Mit unsigned und bitweisem NOT:
1
~0x3Fu
2
= ~0x0000003Fu
3
= ~0b00000000000000000000000000111111u
4
= 0b11111111111111111111111111000000u
5
= 0xffffffC0u
6
= 4294967232
Das ist in uint8_t nicht darstellbar. Bei der Konvertierung nach uint8_t
werden alle Bits bis auf die letzten 8 abgeschnitten, so dass 0xc0 = 192
übrig bleibt. Da der Wert durch die Konvertierung verändert wird, sollte
mit einem expliziten Cast (uint8_t) ausdrücken, dass dies absichtlich
geschieht.
Mit XOR:
1
0x3F
2
^ 0xFF
3
= 0x0000003F
4
^ 0x000000FF
5
= 0b00000000000000000000000000111111
6
^ 0b00000000000000000000000011111111
7
= 0b00000000000000000000000011000000
8
= 0x000000C0
9
= 192
Das ist in uint8_t darstellbar, so dass der Wert bei der Konvertierung
nach uint8_t nicht verändert wird. Deswegen ist es hier in Ordnung, den
expliziten Cast wegzulassen.