Forum: Compiler & IDEs strlen_PF const __flash char


von Walter T. (nicolas)


Lesenswert?

Guten Morgen,
"kauf Dir ein C-Buch!" - habe ich schon, stehe aber trotzdem gerade auf 
dem Schlauch.

Ich habe folgende Deklaration:
1
  typedef enum {fkt,var,none} menuitemtype_t;
2
  
3
  typedef struct {
4
    const __flash char *menutext; // Menueeintrag/Funktionsname
5
    menuitemtype_t type;          // Art des Menueeintrags: Funktion (starten) oder Variable (einstellen)
6
    voidFcn_t fktpointer;         // Funktionszeiger
7
    int8_t *numvar;               // Zeiger auf numerische Variable
8
    int8_t varMin;                // Untere Grenze numerische Variable
9
    int8_t varMax;                // Oberere Grenze numerische Variable
10
  } menudata_t;
und will später in meiner Funktion so lange z"ahlen, bis in "menutext" 
ein Nulleintrag ( {'\0'} ) ist:
1
// Menueeintraege zaehlen
2
uint8_t nMenuEntries = 0;
3
while(strlen_PF(menudata[nMenuEntries].menutext)) nMenuEntries++;
Die Einträge in "menudata" werden wie folgt erzeugt:
1
const __flash char MT_NULL[]         = {'\0'};
2
const __flash char MT_RETURN[]       = "return";
3
const __flash char MT_RESETZ[]       = "Achse Z=0";
4
const __flash char MT_VAR01[]   = "t\eson,min \en =%4i";
5
6
menudata_t menudat[] = {
7
    {MT_RETURN       ,fkt,NULL        ,NULL,0,0},
8
    {MT_RESETZ       ,fkt,edm_resetZ  ,NULL,0,0},
9
    {MT_VAR01        ,var,NULL        ,&tmp,4,64},  
10
    {MT_NULL         ,none,edm_menuhead,NULL,0,0}, // Nullzeile markiert Ende des structs
11
  };

Nun gemahnt mich der Compiler (vermutlich völlig gerechtfertigt): 
"Warnung 1 passing argument 1 of 'strlen_PF' makes integer from pointer 
without a cast".

Nur was erwartet er? Ich stehe gerade auf dem Schlauch.

Viele Grüße
Nicolas

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Die _PF-Funktionen sind etwas schwierig in der Handhabung, weil ein
Zeiger beim AVR-GCC nur 16 bit groß ist, sie aber ein 32-bit-Argument
brauchen.

Bist du dir denn sicher, dass du überhaupt die F-Variante brauchst,
und dass es nicht strlen_P() tun würde (limitiert auf die erste 64 KiB)?

von Karl H. (kbuchegg)


Lesenswert?

> Nun gemahnt mich der Compiler (vermutlich völlig gerechtfertigt):
> "Warnung 1 passing argument 1 of 'strlen_PF' makes integer from
> pointer without a cast".
> Nur was erwartet er?

Was er erwartet ist klar. Das steht in der Fehlermeldung.
makes integer from pointer

D.h. der COmpiler fühlt sich genötigt, den Pointer den du hast
1
   strlen_PF(menudata[nMenuEntries].menutext)
2
             *******************************
in einen Integer (also int) umzuwandeln.

Die Frage ist nur: warum?


Schau dir mal den Protoypen zu strlen_PF an.
Mein gcc ist zu alt, ich hab die _flash Datentypen noch nicht hier 
drauf.
Irgendwo muss es ja einen Protoypen von dieser Funktion geben. Da 
schaust du mal nach, welcher Datentyp dort in der Argumentliste von 
strlen_PF steht.

Es könnte auch sein, dass du eben keinen Protoypen für die Funktion hast 
(Include File vergessen).
Denn in diesem Fall treten in C Default-Annahmen in Kraft. Und die 
besagen in den meisten Fällen: ist nichts anderes bekannt, dann ist das 
ein int.
D.h. wenn es keinen Protoypen gibt, dann muss der Compiler davon 
ausgehen, dass strlen_PF eine Funktion ist, die einen int als Argument 
nimmt und einen int als Returnwert liefert.

Also: der Protoyp für die Funktikon muss her, bzw. überprüfen ob das 
korrekte Include File inkludiert wurde.

von Walter T. (nicolas)


Lesenswert?

Jörg Wunsch schrieb:
> Bist du dir denn sicher, dass du überhaupt die F-Variante brauchst,
> und dass es nicht strlen_P() tun würde (limitiert auf die erste 64 KiB)?

Hallo Jörg,
danke für den Tipp! Du hast Recht, die "_PF"-Funktionen sind reiner 
Overkill. Momentan läuft alles auf einem ATmega32 und mehr als einen 
ATmega644 wird diese Firmware garantiert nie sehen, sonst müßte ich noch 
ganz andere Sachen ändern.

Viele Grüße
Nicolas

von Walter T. (nicolas)


Lesenswert?

Hallo Karl-Heinz,
ihr Experten schaltet wohl immer gleichzeitig den Computer an?

Das libc-Manual sagt, daß die "_PF"-Funktionen einen "uint_farptr_t" 
erwarten-
(http://www.ualberta.ca/~jhoover/web_docs/resources/tools/doc/avr-libc/avr-libc-user-manual-1.7.1/group__avr__pgmspace.html#ga4ce249cbcdb9ff968c76a2d917072da9)

Auf den Unterschied zwischen "pointer in flash" und "farpointer" hat 
mich erst Jörg gebracht- bislang lagen "farpointer" komplett außerhalb 
meines Kenntnisstandes. Also etwas zum im-Hinterkopf-behalten, falls es 
mal irgendwann gebraucht wird.

Danke für die ausführliche Antwort.

Viele Grüße
Nicolas

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.