Hallo! Folgender Minimalcode liefert die Warning. Warum, weiß ich nicht. Ich habe extra einen typecast gemacht.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Danke für Erklärungen!
|
Anzeige
|
warning: cast to pointer from integer of different sizeHallo! Folgender Minimalcode liefert die Warning. Warum, weiß ich nicht. Ich habe extra einen typecast gemacht.
Danke für Erklärungen! Mit
for(unsigned i = 0; i<100;i++)
eeprom_write_byte((unsigned char*)i,0x22);
ist Ruhe.
Was dir der Compiler damit sagen wollte:
(unsigned char) hat 1 Byte, (unsigned char *) hat 2
und das ist zwar nicht falsch, aber könnte ein Hinweis auf ein
Missverständnis sein.
Gast
#2244199
A. K. schrieb: > Was dir der Compiler damit sagen wollte: > (unsigned char) hat 1 Byte, (unsigned char *) hat 2 > und das ist zwar nicht falsch, aber könnte ein Hinweis auf ein > Missverständnis sein. Ich kann es jetzt nicht testen, aber die Warnung müsste auch kommen, wenn für 'i' z.B. uint16_t (32, 64) verwendet wird. Das Entscheidende: 'i' ist eine normale Variable. Da die Funktion eine Adresse erwartet, wird gemeckert. Einfach eine Zahl als Zeiger verwenden, kann ordentlich in die Hose gehen. Denn: woher weißt du denn, dass an den Adressen 0..99 nichts steht? Hier vielleicht zufällig... Deshalb die Warnung. Typecast lieber vermeiden! Man könnte das so machen, dann gibt's (zumindest vom Compiler) hoffentlich nichts zu meckern:
(Für dieses spezielle Problem gibt's natürlich 'eeprom_write_block')
Gast
#2244207
Ralf schrieb: > Denn: woher weißt du denn, dass an den Adressen 0..99 > nichts steht? Grundsätzlich kann ich aber doch davon ausgehen, dass ich der einzige bin, der dahin schreibt, oder? D.h. Wenn ich nirgendwo eine Variable mit EEMEM deklariert habe, und keine meiner libraries den EEPROM beschreibt, sollte ich mich beliebig austoben dürfen. Richtig? Oder optimiert der gcc soweit, dass er Sachen ins EEPROM auslagert?
Gast
#2244214
Verwirrter Anfänger schrieb: > Grundsätzlich kann ich aber doch davon ausgehen, dass ich der einzige > bin, der dahin schreibt, oder? Das ist schon richtig, aber nicht die feine Art! Der Compiler hat schon seinen Grund, rumzumäkeln. Mit dem muss man sich nicht unbedingt anlegen. Und wenn du hier schon, sagen wir mal, schlampig mit den Datentypen umgehst, dann gibt's woanders mit Sicherheit böse Überraschungen! Ralf schrieb: > Ich kann es jetzt nicht testen, aber die Warnung müsste auch kommen, > wenn für 'i' z.B. uint16_t (32, 64) verwendet wird. Ich hätte gedacht, der Wortlaut der Meldung des Compilers sei deutlich genug. Bei unverträglichen Typen klingt das anders und ist auch keine Warnung mehr, sondern ein Fehler. > Das Entscheidende: > 'i' ist eine normale Variable. Da die Funktion eine Adresse erwartet, > wird gemeckert. Drum hatte er dort ja auch den type cast verwendet. Mit dem wird der type check ausgehebelt und pointer-integer Konvertierungen sind legal.
Gast
#2244270
Hab' gerade mal meinen Bastelcomputer hochgefahren. Und Timo P. schrieb: > for(unsigned char i = 0; i<100;i++) > eeprom_write_byte((unsigned char*)i,0x22); geändert zu
... hätte nicht gedacht, dass der Compiler so eine Schlamperei durchgehen lässt. Ralf schrieb: > ... hätte nicht gedacht, dass der Compiler so eine Schlamperei > durchgehen lässt. Das ist nicht die eleganteste Methode, EEPROM Speicher zu allozieren, aber was die Sprache C angeht ist das vollkommen in Ordnung. Und muss auch von jedem Compiler akzeptiert werden. Wenn dir sowas schon gegen die Hutschnur geht, dann schau dir lieber nicht an, was sich hinter Makros wie PORTC verbirgt. Bei deiner Philosophie würde man bei Controller-Programmierung in Warnungen regelrecht ersaufen.
Gast
#2244287
Ich habe noch schnell mal so ein paar 'Konstruktionen' durchprobiert (C++ Builder). Ich hätte gedacht, dass da wenigstens so ein klizekleines Warnungchen kommen müsste. Aber richtig, es gibt ja immer mal wieder spezielle Bibliotheksfunktionen, da werden nur 'int'-s übergeben und das sind dann auch manchmal Adressen. Aber trotzdem (ich hoffe es war nicht ernst gemeint): Verwirrter Anfänger schrieb: > Wenn ich nirgendwo eine Variable mit EEMEM deklariert habe, und > keine meiner libraries den EEPROM beschreibt, sollte ich mich beliebig > austoben dürfen. Ralf schrieb: > Aber trotzdem (ich hoffe es war nicht ernst gemeint): > Verwirrter Anfänger schrieb: >> Wenn ich nirgendwo eine Variable mit EEMEM deklariert habe, und >> keine meiner libraries den EEPROM beschreibt, sollte ich mich beliebig >> austoben dürfen. Womit er Recht hat. Man kann das EEPOM auch als Bytestrom vergleichbar zu einem Diskfile betrachten. Also keine einzelnen Variablen mit mehr oder weniger fester Position. Habe ich auch schon gemacht. Dann sieht das in der Implementierung ungefähr so aus wie hier.
Gast
#2244303
A. K. schrieb: > Dann sieht das in der Implementierung ungefähr so aus wie hier. Mmh, könnte ich mir vorstellen, aber irgendwo sollte schon mal deklariert werden, dass vom EPROM was verwendet wird. Also ich meine, nicht rumtoben.
Gast
#2244741
Meiner Meinung nach ist das API falsch gewählt:
Was hier addr heißt, ist in Wahrheit kein Zeiger, sondern ein Offset. Dieser Sachverhalt sollte sich im API widerspiegeln:
wäre daher meiner Meinung nach besser. A. K. schrieb: > Mit > for(unsigned i = 0; i<100;i++) > eeprom_write_byte((unsigned char*)i,0x22); > ist Ruhe. Ralf schrieb: > geändert zu > for(uint16_t i = 0; i<100;i++) > eeprom_write_byte((uint8_t*)i,0x22); warum schreibt man nicht das hin, was man meint:
willibald schrieb: > Was hier addr heißt, ist in Wahrheit kein Zeiger, sondern ein Offset. nein, es ist ein Zeiger in den eeprom-Adressbereich, der auch mit 0 anfängt. willibald schrieb: > Dieser Sachverhalt sollte sich im API widerspiegeln: > void eeprom_write_byte (uint16_t addr, uint8_t value); > wäre daher meiner Meinung nach besser. wenn schon, dann void eeprom_write_byte (uint16_t offset, uint8_t value); Vlad Tepesch schrieb: > warum schreibt man nicht das hin, was man meint:
Weil man diesen Code vom Compiler um die Ohren gehauen bekommt (i<100).
Gast
#2245078
willibald schrieb: > Meiner Meinung nach ist das API falsch gewählt:void eeprom_write_byte (uint8_t > *addr, uint8_t value); > Was hier addr heißt, ist in Wahrheit kein Zeiger, sondern ein Offset. Offset zu was? Es ist die Adresse einer Speicherstelle, also das, was eben auch in einem Zeiger steht. > Dieser Sachverhalt sollte sich im API widerspiegeln:void eeprom_write_byte (uint16_t addr, uint8_t value); > wäre daher meiner Meinung nach besser. Wenn man dann eine EEMEM-Variable definiert, müßte man deren Adresse immer erst in einen Integer konvertieren, um sie an die Funktion zu übergeben.
Gast
#2245133
Vlad Tepesch schrieb: > nein, es ist ein Zeiger in den eeprom-Adressbereich, der auch mit 0 > anfängt. Zeigertypen sind dann sinnvoll, wenn es etwas gibt, was man damit dereferenzieren kann. Das ist hier nicht der Fall, darum wäre es besser, den Adress-Offset als Integer anzugeben. Mir fällt auch keine sinnvolle Anwendung ein, die an dieser Stelle tatsächlich einen Pointer braucht. Wisst ihr eine? Alle Szenarien, die mir einfallen, führen entweder auf definierte Offsets oder auf Pointer-Differenzen (also auch wieder Ganzzahlen). willibald schrieb: > Zeigertypen sind dann sinnvoll, wenn es etwas gibt, was man damit > dereferenzieren kann. Das ist hier nicht der Fall, darum wäre es besser, > den Adress-Offset als Integer anzugeben. Im Flash auch? Das ist in GCC ebensowenig dereferenzierbar. Die Leute würden sich über die vielen dann notwendigen Casts sicherlich wenig freuen. Und beides verschieden zu definieren wäre grotesk. > Wisst ihr eine? Ganz normale EEPROM Variablen.
Gast
#2245153
willibald schrieb: > Mir fällt auch keine sinnvolle Anwendung ein, die an dieser Stelle > tatsächlich einen Pointer braucht. Wisst ihr eine? Siehe http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#EEPROM > Alle Szenarien, die mir einfallen, führen entweder auf definierte Offsets oder auf > Pointer-Differenzen (also auch wieder Ganzzahlen). Nochmals: Differenzen zu was?
Gast
#2245164
OK, dieser EEMEM-Ansatz war mir nicht bekannt. Liegt vermutlich daran, dass ich kein AVR-Anwender bin. Aber ihr habt Recht, das Konzept ist stimmig. Wieder was gelernt. Bei den Xmegas liegt das EEPROM zudem im Datenadressraum und ist folglich dereferenzierbar. Ralf schrieb: > ... hätte nicht gedacht, dass der Compiler so eine Schlamperei > durchgehen lässt. Was erwartest du? Mit dem Cast sagst du dem Compiler explizit: Halt die Klappe.
Gast
#2245921
Karl Heinz Buchegger schrieb: > Was erwartest du? > Mit dem Cast sagst du dem Compiler explizit: Halt die Klappe. Jaa, jaa. ;-) Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|