Is it possible to define a function using a callba

2020-04-07 20:16发布

I'm interested in defining a function using a predefined callback type.

Let's assume I have defined callback type:

typedef BOOL (*is_trigger_required_cb)(void);

Now I would like to declare and define a function using the above type.

I would like to do something like:

is_trigger_required_cb my_func { /* function implementation which accepts void and returns BOOL */ }

This won't compile due to:

error: expected ';' after top level declarator

To my understanding it is not possible since the compiler refers to the callback type merely as type-safe function pointer and cannot be used for function definition. In case there's a change of callback type, it would break the compilation thus type safety is maintained.

标签: c callback
3条回答
贪生不怕死
2楼-- · 2020-04-07 20:34

No, you cannot do that. You can only use those typedefs for function pointers. You can define just a function type like Storyteller did in their answer. But as you can see it does not really make things better. Neither does my solution.

Use a macro (no, don't do it)

One thing you can do, but I would strongly advice against it, is using a macro:

#define f(fname) BOOL fname (void)

f(foo) {
    return 1;
}

The above will give you a function foo that takes zero arguments and return a BOOL. It will come with a lot of limitations though. If you want to support arguments, you can do something like this:

#define binary_bool(fname, arg1, arg2) BOOL fname (arg1, arg2)

binary_bool(equals,x,y) {
    return x==y;
}

Again, I advice against it. I'm just showing that something similar to what you want is theoretically possible. Macros like this often makes debugging very tricky.

TL;DR

No, you cannot do that in a good way in C

查看更多
Juvenile、少年°
3楼-- · 2020-04-07 20:36

You cam approximate it if you define function types.

typedef BOOL is_trigger_required_cb(void);

that will make the callback be an explicit pointer (something I consider a plus)

is_trigger_required_cb *cb;

and will allow you to at least declare functions with that type:

is_trigger_required_cb my_func;
BOOL my_func (void) {
  // Do stuff
}

You still need to repeat the full prototype at the point of definition, there is no getting around that, because the grammar forces your hand. But at least you get the type checking you were after, since the declaration must match the definition of a prototyped function.

It may appear arcane however, since this is not something one normally sees. I suggest you weigh the merits of it against the need to explain it.

查看更多
孤傲高冷的网名
4楼-- · 2020-04-07 20:41

The typedef is_trigger_required_cb is not an alias of a function type but pointer to function. Additionally C11 6.9.1p2 says that

the identifier declared in a function definition (which is the name of the function) shall have a function type, as specified by the declarator portion of the function definition. [162]

with the footnote 162 saying that

162) The intent is that the type category in a function definition cannot be inherited from a typedef[...]

i.e. you just cannot do it - the reason would be obvious - the function type does not name the parameters, hence it could not be used to declare the parameters within the function body.

查看更多
登录 后发表回答