Forum: Compiler & IDEs Warnung bei Übergabe von Zeigern auf Funktionen


von Grübler (Gast)


Lesenswert?

Ich habe mit WinAVR eine Menusteuerung für einen ATmega88
geschrieben. Mit einem Inkrementalgeber kann man sich durch
ein Haupmenu drehen, ein Untermenu auswählen und hier
schlussendlich eine Funktion auswählen.
Verlässt man dies Funktion, landet man wieder im Untermenu
u.s.w
Es funktioniert auch alles prima, ich kann es selbst noch
nicht glauben ;-)
Es kommen aber eine Warnmeldungen nach dem Kompilieren, die
ich nicht so recht deuten kann.

Hier die entscheidenden Programmausschnitte.

Ich habe Arrays mit den Zeigern auf die Funktionen angelegt.
Hier das Array für den „Regler“:

1
typedef void(*p_of_funk)(void); //p_of_funk ist ein Datentyp,
2
//der einen Zeiger auf eine Funktion bildet. Damit werden
3
// Arrays mit den Adressen der Funktionen erstellt.
4
5
6
//Funktionsprototypen der 3 Funktionen im Menu  > Regler <
7
void Re_Wahl(void);
8
void Re_Para(void);
9
void Re_Start(void);
10
//Das Vektor Array für das Re-Menu
11
p_of_funk V_Arr_Re[3]={Re_Wahl, Re_Para, Re_Start};

Um ein Menu anzuzeigen, rufe ich die folgende Funktion auf.
Mit index wird eine Zahl übergeben, damit u. A. die richtigen
Menutexte angezeigt werden. Weiterhin will ich hier das Array
mit den Funktionszeigern übergeben. Im Menu wird dann eine
„menu_nr“ gewählt (ASCII Zeichen 1…3) und die entsprechende
Funktion aus dem Array gestartet. Hier ist nur diese einzige
Programmzeile aus der Funktion Menu dargestellt.

1
void menu(unsigned char index, p_of_funk vek[])
2
}
3
4
  vek[menu_nr - '0' - 1](); //Hier wird die Funktion gestartet
5
  
6
}


Die Warnmeldung:
warning: passing argument 2 of 'menu' from incompatible pointer type

entsteht beim Aufrufen der Funktion menu

Hier der Aufruf des Regler-Menus.

1
void Regler(void)
2
{
3
 menu(Regler_M, &V_Arr_Re);
4
 return;
5
}

Ich hoffe ich habe mich halbwegs klar ausgedrückt. Ich möchte
keinem zumuten, mein ganzes Programm zu sichten
(bis jetzt 28 Seiten Schriftgröße 10)

Zum Schluss noch mal meine Fragen:
Wie muss ich die Funktionsaufrufe richtig schreiben,
damit keine Warnmeldung mehr entsteht?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Die Aufrufe der Funktionspointer sind gar nicht das Problem, wie Du auch 
erkennst, wenn Du Dir die Fehlermeldungen mal genauer ansiehst:
1
void menu(unsigned char index, p_of_funk vek[])
2
}  
3
4
  vek[menu_nr - '0' - 1](); //Hier wird die Funktion gestartet
5
  
6
}

Offensichtlich hast Du Dir das aus dem Gedächtnis so zurechtgetippelt. 
Kopiere Sourcecode, tippe nichts aus dem Gedächtnis ab, denn hier sind 
mindestens zwei schwere Fehler enthalten.
1
void menu(unsigned char index, p_of_funk vek[])
2
{  
3
  vek[index - '0' - 1](); //Hier wird die Funktion gestartet
4
}


> Die Warnmeldung:
> warning: passing argument 2 of 'menu' from incompatible pointer type

menu erwartet also ein Array, Du aber rufst es mit einem Pointer 
auf:
1
void Regler(void)
2
{
3
 menu(Regler_M, &V_Arr_Re);
4
 return;
5
}


Woraus das Array besteht und worauf der Pointer zeigt, ist hier 
unabhängig vom Funktionspointer.

Du kannst menu auch so schreiben:
1
void menu(unsigned char index, p_of_funk *vek)
2
{  
3
  vek[index - '0' - 1](); //Hier wird die Funktion gestartet
4
}

und Dich hier des Array/Pointer-Dualismus bedienen.

Du solltest allerdings noch unbedingt eine Bereichsüberprüfung 
durchführen, denn was geschieht, wenn die Funktion mit nicht 
vorgesehenen Werten für "index" aufgerufen wird?

von Rolf Magnus (Gast)


Lesenswert?

Rufus t. Firefly schrieb:
1
> void menu(unsigned char index, p_of_funk vek[])
2
> {  
3
>   vek[index - '0' - 1](); //Hier wird die Funktion gestartet
4
> }
>
>
>> Die Warnmeldung:
>> warning: passing argument 2 of 'menu' from incompatible pointer type
>
> menu erwartet also ein Array,

Eigentlich nicht. Es erwartet einen Zeiger auf p_of_funk.

> Du aber rufst es mit einem Pointer

Er ruft es mit einem Zeiger auf ein Array aus p_of_funk auf.

> auf:
1
> void Regler(void)
2
> {
3
>  menu(Regler_M, &V_Arr_Re);
4
>  return;
5
> }

V_Arr_Re ist ein Array aus p_of_funk. &V_Arr_Re ist die Adresse dieses 
Arrays und ist vom Typ "Zeiger auf 3-elementiges Array aus p_of_funk". 
Die Funktion erwartet aber einen Zeiger auf p_of_funk. Daher stimmt der 
Zeigertyp nicht. Um das zu ändern, müßte man lediglich beim Aufruf das & 
wegmachen, da bei Übergabe des Arrays an die Funktion automatisch ein 
Zeiger auf das erste Element daraus wird.
Alternativ ginge auch:
1
  menu(Regler_M, &V_Arr_Re[0]);

Also explizit hinschreiben, daß man die Adresse des ersten Elements 
haben will.

von Grübler (Gast)


Lesenswert?

Hallo Rufus, Hallo Rolf

Danke für Eure Mühe.
Nach einer Stunde an der frischen Luft
habe ich noch mal über meinen Code
geschaut und das entdeckt, was Rolf
hier gut beschrieben hat.
Ich hab die "&" im Aufruf entfernt
und die Warnungen sind weg.

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.