Forum: Mikrocontroller und Digitale Elektronik Funktionspointer: Welcher code ist richtig


von M. Н. (Gast)


Lesenswert?

Hallo. Ich habe eine ganz kurze Frage. Ich würde es ausprobieren, habe 
allerdings keinen Compiler hier.

Ich habe mir gerade diesen Artikel durchgelesen:

http://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung

darin wird ein Funktionspointer wie folgt verwendet:
1
void (*bootloader)( void ) = 0x0C00;
2
//Aufruf:
3
bootloader();

Ich kenne jedoch den Aufruf als:
1
(*bootloader)();
Was ist richtig?
Geht beides?

von Cyblord -. (cyblord)


Lesenswert?

Funktionspointer kann man wie normale Funktionen aufrufen. Somit ist 
Variante 1 auf jeden Fall richtig. 2 wird aber auch gehen.
Fazit: Beides ok.

von Karl H. (kbuchegg)


Lesenswert?

M. H. schrieb:

> Geht beides?

Durch entsprechende Definitionen im C Standard geht beides.

Die Version ohne * ist die eigentlich richtige, aber durch entsprechende 
Regelungen mündet die Version mit dem * in derselben Gasse.

Das ist genau dasselbe, wie die Zuweisung an einen Funktionspointer. 
Durch entsprechende Konvertier-Regelungen münden
1
void foo( void )
2
{
3
  ..
4
}
5
6
void (*ptr)( void );
7
...
8
  ptr = foo;
9
  ptr = &foo;

in identischer Semantik.

von (prx) A. K. (prx)


Lesenswert?

Das wird ziemlich konsequent, wenn man () als Dereferenzierung eines 
Funktionszeigers betrachtet.

Die Versionen mit * und & sind eigentlich nur Konzessionen an jene 
Leute, die mit dieser inneren Logik auf Kriegsfuss stehen.

von Karl H. (kbuchegg)


Lesenswert?

A. K. schrieb:
> Das wird ziemlich konsequent, wenn man () als Dereferenzierung eines
> Funktionszeigers betrachtet.
>
> Die Versionen mit * und & sind eigentlich nur Konzessionen an jene
> Leute, die mit dieser inneren Logik auf Kriegsfuss stehen.

Ich hab mir mal die Mühe gemacht, aus dem Standard rauszusuchen, warum 
das überhaupt funktioniert, bzw. wie die Definitionen da laufen

Der Name einer Funktion ist im C Standard ein 'Function Designator', der 
bei Bedarf automatisch in einem 'Pointer to function' konvertiert wird. 
(6.3.2 - 4)

Weiters heisst es
1
6.5.2.2 Function calls
2
Constraints
3
1 The expression that denotes the called function (80) shall
4
  have type pointer to function

Fussnote 80 besagt
1
80) Most often, this is the result of converting an identifier that
2
 is a function designator

D.h. das man überhaupt
1
void foo( void )
2
{
3
  ..
4
}
5
...
6
    foo();
schreiben kann, liegt daran, dass der Function Designator 'foo' 
automatisch in einen Function Pointer umgewandelt wird, über den dann 
die Funktion aufgerufen wird.

Wenn man also schreibt
1
void (*ptr)( void ) = foo;
2
...
3
   ptr();
dann wird die Funktion aufgerufen, weil ptr schon den eigentlich 
korrekten Datentyp 'Pointer to function' hat.
Schreibt man hingegen
1
    (*ptr)();
dann mündet die Dereferenzierung des Pointers laut 6.5.3.2 - 4 wieder in 
einem Function Designator, der dann konzeptionell wieder in einen 
Function Pointer implizit umgewandelt wird um die Funktion aufzurufen.

von M. Н. (Gast)


Lesenswert?

Vielen Dank für die ausführlichen Antworten.

Dann wäre das geklärt :D

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.