Archiv verlassen und diese Seite im Standarddesign anzeigen : Compiler-Warnungen...
Hallo!
Ich hab einige Compiler-Warnungen, die ich nicht verstehe (was daran liegen könnte, dass ich C- und AVR-Neuling bin).
eeprom_write_byte(i,cUSART_inp[i]);
Diese Zeile bzw. der Parameter "i" (unsigned short int) erzeugt die folgende Warnung:
../testc.c:72: warning: passing argument 1 of 'eeprom_write_byte' makes pointer from integer without a cast
Was muss ich tun, um die Meldung zu verhindern? Welchen Hintergrund hat das? Eigentlich funktioniert nämlich alles so, wie es soll.
Bei einigen Funktionen (realloc, free, itoa) wird ebenfalls eine Warnung ausgegeben:
../testc.c:66: warning: implicit declaration of function 'realloc'
Wieso implicit declaration?? Die Funktionen laufen ohne Probleme, sind also bekannt. Ich würde die Meldung so verstehen, dass der Funktionsprototyp fehlt. Aber das kann doch nicht sein, oder? Schließlich kommen diese Funktionen ja nicht von mir...
Was muss ich tun, um mein Programm fehler- und warnungsfrei zu kompilieren??
Gruß Matze
Hi,
bei eeprom_write_byte wird als erster Parameter ein Zeiger auf ein Byte erwartet, du übergibst allerdings den Wert. Deshalb die Warnung.
Für realloc, free und itoa musst du die entsprechenden Headerdateien einbinden. Dies ist hier die stdlib.h, das machst du so: (bis oben im Programm)
#include <stdlib.h>
Viele Grüße
CsT
Danke, CsT!
Wow, heißt das, dass bislang realloc() und free() gar nicht funktioniert haben??
Das könnte vielleicht erklären, warum das Programm bislang zwar (scheinbar) funktioniert hat, aber nach mehreren Ein- und Ausgaben immer hängenblieb.
Warum lässt der Compiler sowas durchgehen? In dem Fall sollte er doch mit einem "undefined function" oder so abbrechen, oder sehe ich das falsch?
Das erste verstehe ich noch nicht so richtig. Ich bin dank deinem Tipp zu dem Schluss gekommen, dass mein Wert grundsätzlich natürlich genutzt werden kann, jedoch gecastet werden muss. Mit "Zeiger auf Byte" meinst du damit (unsigned char *)i ? Oder liege ich da auch wieder falsch? Zumindest kompiliert er so warnungsfrei.
Gruß Matze
Richtig, free, realloc usw. sollten bis jetzt nicht richtig funktioniert haben. Der Compiler warnt dich hinreichend, er sieht deine Benutzung quasi als Funktionsdeklaration an. Warnungen sollten nie ignoriert werden ..
Zu 2.
Zeiger übergibt man, indem man ein "&" vor den Variablenname schreibt.
Also: eeprom_write_byte(&i,cUSART_inp[i]);
Möchte jetzt keine weiteren Ausführungen zu Zeigern schreiben .. wenn du nachlesen möchtest: http://www.highscore.de/cpp/einfuehrung/zeiger.html
Mit dem & wird quasi die Adresse der Variablen übergeben.
Grüße
CsT
Ja, ich weiß schon grundsätzlich, wie Zeiger funktionieren (zumindest grob). Ich habe auch zuerst versucht, die Adresse von i zu übergeben. Dann kam allerdings die folgende Warnung:
../testc.c:75: warning: passing argument 1 of 'eeprom_write_byte' from incompatible pointer type
Richtig scheint zu sein:
eeprom_write_byte((uint8_t*)i,cUSART_inp[i]);
Den Tipp hab ich eben in einem anderen Forum gefunden. Erklären kann ich ihn allerdings nicht, ebensowenig erkenne ich beim kurzen Test einen Unterschied, außer eben, dass die Compiler-Warnung weg ist.
Na ja, jetzt ist Feierabend. Damit kann ich mich morgen weiter rumärgern.
Nochmals VIELEN DANK, CsT!
Keiner eine Idee, warum bei Funktion eeprom_write_byte() diese cast auf uint8_t* nötig ist? Würde mich sehr interessieren.
Schließlich verstehe ich nicht, warum da ein Pointer übergeben werden soll. Dieser zeigt ja schließlich nicht auf die Adresse im EEPROM, die beschrieben werden soll, sondern nur auf die Adresse von i, in der dann steht, welches Byte (bei mir 0-127) geschrieben werden soll. Und es klappt ja auch mit meiner ursprünglichen Methode ( eeprom_write_byte(i,cUSART_inp[i]) ).
Lasst mich raten! Die Antwort ist: Es ist so, also akzeptiere es!
Zeiger zu übergeben ist sauberer bei solchen Sachen. Es muss nicht extra eine Kopie angelegt werden, was bei Parameterübergabe by value nötig ist. Hat also programmiertechnisch einige Vorteile, man könnte es auch "normal" mit by value lösen ..
Warum das mit dem & nicht funktioniert frage ich mich .. sollte eigentlich funktionieren.
../testc.c:75: warning: passing argument 1 of 'eeprom_write_byte' from incompatible pointer type
Das diese Warnung beim Versuch, die Adresse von i zu übergeben, produziert wird, könnte doch daran liegen, dass i unsigned short ist (16 Bit), jedoch ein 8-Bit Pointer erwartet wird. Hatte ja nicht den ganzen Code gepostet, sonst hättet ihr das vielleicht gesehen. Liege ich da richtig?
Ich habe noch ein weiteres interessantes Phänomen:
eeprom_write_byte((uint8_t*)(unsigned int)eeprom_get_next_byte(iEEPROM_lastByte),cUSART_ inp[i]);
/***************/
uint8_t eeprom_get_next_byte(uint8_t iLastByte) {
/***************/
uint8_t iNextByte = iLastByte + 1;
//
if(iNextByte > EEPROM_MAX_BYTE) {
iNextByte = 0;
}
//
iEEPROM_lastByte = iNextByte;
return(iNextByte);
}
Es ist der gleiche Ausdruck, nur das i durch die Funktion eeprom_get_next_byte() ersetzt wurde. Diese liefert uint8_t zurück. Ein Cast nach uint8_t* gibt aber ebenfalls eine Warnung. Es funktioniert nur der Doppel-Cast (uint8_t*)(unsigned int).
Warum muss der 8-Bit-Wert erst in einen 16-Bit-Wert umgewandelt werden, um dann einen Pointer auf einen 8-Bit-Wert zu bekommen?? Ist das nicht unlogisch? Muss ich beim Programm nun darauf achten, dass mindestens ein Byte des SRAM freibleibt, da es während dieser Zeile gebraucht wird? Oder geschieht diese Konvertierung nicht im SRAM?
Bin schon auf eure Antworten gespannt!
Gruß Matze
SprinterSB
22.06.2007, 15:25
eeprom_write_byte((uint8_t*)(unsigned int)eeprom_get_next_byte(iEEPROM_lastByte),cUSART_ inp[i]);
Gruß Matze
Irgendwas stimmt mit deinen Argumenten/Prototypen nicht.
Du liest ein Byte (Datum) und das soll als EEPROM-Adresse interpretiert werden? Dann das:
eeprom_write_byte((void*) eeprom_get_next_byte (iEEPROM_lastByte), cUSART_inp[i]);
Morgen!
Sorry, dass ich solange nicht gepostet habe.
Deinen Tipp mit dem Cast zum void-pointer habe ich ausprobiert, allerdings kommt dann die folgende Compiler-Warnung:
../testc.c:169: warning: cast to pointer from integer of different size
Am Prototyp sollte es nicht liegen, da die Funktion nicht von mir kommt, sondern in der eeprom.h enthalten ist:
static inline void __attribute__ ((always_inline)) eeprom_write_byte (uint8_t *addr,uint8_t value);
void eeprom_write_byte (uint8_t *addr,uint8_t value)
{
__asm__ __volatile__ (
"mov __tmp_reg__,%1" CR_TAB
XCALL " __eeprom_write_byte_" _REG_LOCATION_SUFFIX
: "+x" (addr)
: "r" (value)
: "memory"
);
}
Wie gesagt, wenn iEEPROM_lastByte eine uint8_t ist, geht der Cast zu uint8_t* nicht bzw. produziert eine Warnung. Bei einer uint16_t geht's, ebenso funktioniert natürlich der Umweg über den zweifachen Cast.
Dass in der Funktion Assembler-Anweisungen verarbeitet werden, kann doch auch nicht der Grund sein, oder? Schließlich meckert der Compiler nur aufgrund des Argumenten-Typs, unabhängig vom Inhalt der Funktion. Richtig?
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.