[C] Funktion, die Ihren eigenen Typ als Argument bekommt

Gast #5699204
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?
Gast
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
}
Gast
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
}
Gast
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 von einem Moderator gelöscht.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.