Forum: Mikrocontroller und Digitale Elektronik [C] Funktion, die Ihren eigenen Typ als Argument bekommt


von Peter F. (Gast)


Lesenswert?

Hallo,

ich möchte eine Funktion deklarieren (oder am besten als typedef), die 
als Argumente eine Integer und einen Funktionszeiger auf genau so eine 
Funktion, wie sie selbst eine ist, akzeptiert.
Wenn ich schreibe
1
typedef int Func_t( int, Func_t* );
geht das ja nicht, weil der Typ Func_t noch nicht bekannt ist.

Aber so geht's auch nicht:
1
typedef int Func_t( int, int(*)() );
2
3
testfunc(int i, Func_t *f) {
4
     return 0;
5
}
6
Func_t *funcptr = testfunc;
Hier meckert der Compiler natürlich, dass *funcptr und testfunc nicht 
vom selben Pointer Typ sind.
Ich müsste casten:
1
Func_t *funcptr = (Func_t*)testfunc;
Kann man denn einen Typ basteln, der als (zweites) Argument einen Zeiger 
auf den eigenen Typ nimmt?

von Tom (Gast)


Lesenswert?

Die Lösung für alle abstrusen Probleme in C ist "Das Problem in ein 
struct stecken, schon funktioniert es".
1
#include <stdio.h>
2
3
typedef struct Foo
4
{
5
    void (*call)(struct Foo, int);
6
} Foo;
7
8
void bar(Foo foo, int i)
9
{
10
    if (i <= 0)
11
        return;
12
    printf("%d\n", i);
13
    foo.call(foo, i-1);
14
}
15
16
int main(void)
17
{
18
    bar((Foo){bar}, 7);
19
    return 0;
20
}

von nocheinGast (Gast)


Lesenswert?

Also in C kann man sowas doch mit dem Präprozessor zusammenbauen 
(vorausgesetzt ich hab überhaupt die Frage richtig verstanden):
1
#define tdef(Name, R, ...) \
2
    typedef R(*Name)(__VA_ARGS__, R(*)(__VA_ARGS__))
3
    
4
tdef(Funktion, int, char, int);
5
6
7
int f(char a, int b, int (*c)(char a, int b)) {
8
    return c(a, b);
9
}
10
11
int x(char a, int b) {
12
}
13
14
void y(char a, int b) {
15
}
16
17
int main() {
18
    Funktion fp = f;
19
    
20
    fp(1, 2, x);
21
    fp(1, 2, y);  // Fehler.
22
}
Ich hoffe, ich mach hier keinen Unsinn...

In C++ könnte man das mit einem Template lösen:
1
#include <functional>
2
3
template <typename R, typename... Args>
4
using Funktion = std::function<R (Args..., std::function<R (Args...)>)>; 
5
6
int f(char a, int b, std::function<int (char a, int b)> c) {
7
    return c(a, b);
8
}
9
10
int x(char a, int b) {
11
}
12
13
void y(char a, int b) {
14
}
15
16
int main() {
17
    Funktion<int, char, int> fp = f;
18
    
19
    fp(1, 2, x);
20
    fp(1, 2, y);  // Fehler.
21
}

von Peter F. (Gast)


Lesenswert?

Tom schrieb:
> "Das Problem in ein
> struct stecken, schon funktioniert es".
Danke!
Das funktioniert, denn da erscheint das zweite "struct Foo" in einem 
anderen Block, wo es schon bekannt ist.

nocheinGast schrieb:
> Also in C kann man sowas doch mit dem Präprozessor zusammenbauen
Hm, ich glaube nicht, denn auch der Präprozessor muss ja Code 
generieren, den der Compiler als gültig ansieht.

nocheinGast schrieb:
> int f(char a, int b, int (*c)(char a, int b)) {
>     return c(a, b);
> }
Auch hier ist ja *c nicht vom selben Typ wie f.

Beitrag #5699472 wurde vom Autor gelöscht.
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.