Forum: Compiler & IDEs Wie herausfinden ob an der EEPROM ein String ist?


von AVRli (Gast)


Lesenswert?

Hallo zusammen,

ich möchte gerne wissen ob ein bestimmter Bereich im EEPROM einen String 
enthält. Dazu habe ich mir eine Unterfunktion geschrieben die auch auf 
den ersten Blick funktioniert aber der Compiler meckert mich nun mit:

"test.c:2841: warning: pointer targets in passing argument 1 of 
'chk_eep_str' differ in signedness

an.

Da ich nun gelernt habe der Compiler hat immer recht oder mit anderen 
Worten, nimm auch die Warnungen ernst, würde mich interessieren was
ich übersehen habe / wie man es richtig macht.

Die Funktion ist diese:
1
uint8_t chk_eep_str(const uint8_t *eepstr)
2
{
3
  char chr;
4
  chr = eeprom_read_byte(eepstr);
5
    if ((chr != 0) && (chr != 255)) return 1;
6
  else return 0;
7
}

...der Aufruf erfolgt mit...
1
if ( chk_eep_str(eep_buf[p+i].name) ) {
2
  lcd_eep_string(eep_buf[p+i].name);
3
}
4
else
5
{
6
  lcd_string("leer");
7
}


Danke falls sich das einer ansieht... ;-)

Gruß AVRli...

von Ohm (Gast)


Lesenswert?

Ohne Gewähr: Laut Funktionsdefinition zeigt der Pointer auf einen 
unsigned, der übergebene Wert ist aber signed.

von Volker Z. (vza)


Lesenswert?

Wie ist .name definiert ?

von AVRli (Gast)


Lesenswert?

Volker Zabe schrieb:
> Wie ist .name definiert ?

Als char wie ich gerade sehen... :-(

von Peter D. (peda)


Lesenswert?

Der AVR-GCC ist ziemlich pingelig.

Stringpointer akzeptiert er nur als (char*) oder (void*).
Alles andere meckert er an, auch (int8_t*).

Am besten alles nach (void*) casten, dann gibt er Ruh.


Peter

von AVRli (Gast)


Lesenswert?

So ist erstmal Ruhe...
1
uint8_t chk_eep_str(const char *eepstr)
2
{
3
  char chr;
4
  chr = eeprom_read_byte(eepstr);
5
    if ((chr != 0) && (chr != 255)) return 1;
6
  else return 0;
7
}

Peter Dannegger schrieb:
> Am besten alles nach (void*) casten, dann gibt er Ruh.

Also ich tu mich echt schwer mit den Zeigern und dem "casten" ich hab 
einfach noch nicht kapiert was man damit genau macht.


Danke an alle!!!
Gruß AVRli...

von Rolf M. (rmagnus)


Lesenswert?

Peter Dannegger schrieb:
> Der AVR-GCC ist ziemlich pingelig.

Zu Recht.

> Stringpointer akzeptiert er nur als (char*) oder (void*).

Alle anderen Typen wären auch falsch.

> Alles andere meckert er an, auch (int8_t*).
>
> Am besten alles nach (void*) casten, dann gibt er Ruh.

Oder halt gleich den richtigen Typ verwenden. Es ist schon Absicht, daß 
es in C typisierte Zeiger gibt.

AVRli schrieb:
> Peter Dannegger schrieb:
>> Am besten alles nach (void*) casten, dann gibt er Ruh.
>
> Also ich tu mich echt schwer mit den Zeigern und dem "casten" ich hab
> einfach noch nicht kapiert was man damit genau macht.

Dann solltest du es auch nicht leichtfertig einsetzen, denn damit kann 
man ziemlichen Mist produzieren, wenn man es falsch einsetzt. Du wirst 
allerdings nicht drum herum kommen, dir das mal genauer anzusehen.

von AVRli (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Dann solltest du es auch nicht leichtfertig einsetzen, denn damit kann
> man ziemlichen Mist produzieren, wenn man es falsch einsetzt. Du wirst
> allerdings nicht drum herum kommen, dir das mal genauer anzusehen.

Gut was ein Zeiger ist, ist mir klar. Warum man den nimmt ist auch klar.
Nur wann castet man nun??? Was ist das "casten"? fragendgucken

Gruß AVRli

von Karl H. (kbuchegg)


Lesenswert?

AVRli schrieb:

> Nur wann castet man nun???

Wenn absolut gar nicht anders geht.
Casts sind Waffen und dementsprechend spärlich und überlegt sollte man 
sie auch einsetzen.

> Was ist das "casten"?

Wenn man dem Compiler ein X für ein U vormachen will (hier in diesem 
speziellen Fall des Umcastens eines Pointers).
An dieser Stelle bedeutet der Cast:
"Lieber Compiler. Wir tun jetzt einfach mal so, als ob dort im Speicher 
das und das liegen würde. Ja, ich weiß, das es das nicht tut, aber tun 
wir halt einfach mal so. Also halt die Klappe und mach es einfach!"
Aber, wie es halt manschmal so ist, ein Esel wird nicht deswegen zum 
Pferd, weil man ihn Pferd nennt.



Du solltest dir das wilde Mischen von
  uint8_t
  int8_t
  char

abgewöhnen. Auch wenn alle 3 Datentypen letztendlich in einem Byte im 
Speicher münden, so sind sie doch verschiedene Dinge. Die einen sind mit 
Vorzeichen, die anderen ohne. Ob ein char ein Vorzeichen hat oder nicht, 
entscheidet eine Einstellung im Compiler. Es ist daher vernünftig, 
diesen Datentyp auch extra zu sehen


   char        für alles was Stringverarbeitung bedeutet. Also
               überall wo es um Texte geht

   int8_t      ein kleiner Integer mit Vorzeichen (also zum rechnen!)

   uint8_t     ein kleiner Integer ohne Vorzeichen
               auch zum rechnen, aber diesmal ohne Vorzeichen.
               Vulgo: Ein Byte

verwende die Datentypen in diesem Sinne und du wirst weniger Ärger 
haben.

Deine Funktion chk_eep_str behauptet von sich, dass sie überprüft ob im 
Speicher ein String liegt. Ergo - Textverarbeitung. Also ist der 
angemessene Datentyp dafür ein

  uint8_t chk_eep_str(const char *eepstr)
  {
     ...
  }

von AVRli (Gast)


Lesenswert?

Besten Dank für die ausführlich Erklärung und ja ich bin überzeugt, ich 
werde mir das "wilde Mischen" abgewöhnen!!! :-D

Gruß AVRli...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.