Interesting, I had never thought of that solution before.
The first one is of course standard, and I'd bet that's what you would find in the vast majority of C projects[*].
The second in theory takes memory, since you're actually declaring a data object full of function pointers. You would of course also need to initialize the kernel
variable, i.e. have something like:
...
} kernel = {
.init = kernel_init,
.start = kernel_start,
};
But oooh there you go with prefixed functions again. To remove the need for those, the functions have to be static
, which I guess is possible if you add extern
to the struct
declaration in the kernel.h
.
So a more complete example could be:
// kernel.h (public header)
typedef struct kernel_api {
void (*init)(void);
int (*start)(void* foo);
} kernel_api;
extern const kernel_api kernel;
// in kernel.c
static void init(void)
{
...
}
static int start(void *foo)
{
..
}
const kernel_api kernel = {
.init = init,
.start = start,
};
This might work, but I haven't tried it.
Finally, having explicit data means it takes a sufficiently smart compiler to optimize those out and make more direct calls, but I haven't tried it and it's a bit risky to depend on such. Interesting.
[*] I think I just statistically claimed that I have seen (or thought of) the vast majority of the world's C projects, but that's of course not true. :)