1


I want to create a task struct containing a function pointer to a callback to execute said task. The task contains the parameters so I would like to pass a "this/self" pointer of the struct to the callback executor function. This creates circular dependencies and I've been digging around trying various forward declarations etc but can't seem to get it right. Am I missing something that makes this impossible, or is it just that my C syntax wizardry is horribly weak. Changing the task* to a void* seems like cheating?

in task.h :

// create a function pointer type signature for executing a task
typedef int (*executor) (task* self);

// create a task type
typedef struct {
    executor exec;  // the callback to execute the task
    ... // various data for the task
} task;
netjiro
  • 35
  • 2
  • 7
  • 1
    See this http://stackoverflow.com/questions/9999512/forward-declaration-of-a-struct-in-c – Rohan May 12 '15 at 08:31
  • Excellent answers below. Thanks guys. Followup reading here: http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions – netjiro May 12 '15 at 08:47
  • @Rohan I'd rather close that link as a duplicate to this question, as there is less "fluff code" in this one. – Lundin May 12 '15 at 09:40

3 Answers3

1

Forward declare struct task, then declare the function pointer using struct task, then declare the struct task and the typedef task.

struct task;
typedef int (*executor) (struct task* self);

typedef struct task {
    executor exec;  // the callback to execute the task
    ... // various data for the task
} task;

Or as Jens suggested:

First typedef task with a forward declaration of struct task, then declare the function pointer (using the typedef task) and the struct task.

typedef struct task task;
typedef int (*executor) (task* self);

struct task {
    executor exec;  // the callback to execute the task
    ... // various data for the task
};
Werner Henze
  • 16,404
  • 12
  • 44
  • 69
1

You have to add an incomplete type declaration before, telling the compiler that the type will be defined later. You can "abuse" the fact that so-called struct tags have their own namespace, separate from type names So a struct tag name can be the same as a type name:

typedef struct task task; // typedef a struct task as "task"
typedef int (*executor) (task* self); // pointer to incomplete type

typedef struct task { // re-use struct tag name here to complete the type
    executor exec;
} task; // typedef a name for the completed type

...
task t;
Lundin
  • 195,001
  • 40
  • 254
  • 396
0

Typedef and forward declare the struct first, and it should work, sth like that:

#include <stdio.h>

typedef struct task task;
typedef int (*executor) (task* self);

struct task {
    executor exectr;
    int a;
};

int exec(task* self) {
    return self->a;
}

int main(int, char**) {
    task a = { .exectr = exec, .a=10};
    printf("%d\n",a.exectr(&a));
    return 0;
}
alagner
  • 3,448
  • 1
  • 13
  • 25