[Swan-dev] typing libevent callback functions

Andrew Cagney andrew.cagney at gmail.com
Thu Jan 29 19:02:44 EET 2015


Here's probably what is now down to 1.5 cents worth of opinion:

- the compiler can detect code has screwed up function parameter types
- just need -Wall -Werror so that prototypes are visible and badness
has a hard fail - the typedef isn't needed

- using a typedef to declare function parameters can help make the
code more readable:
    void register_callback(void (*callback)(struct cb_context *context));
vs
   typedef void (cb_t)(struct cb_context *context);
   void register_callback(cb_t *callback);

- on the other hand, trying to enforce a rule where all callback
functions must first be declared using that typedef is, I think, of
diminishing return. Since -Wall -Werror will barf anyway, the effort
might be better spent on enforcing that.
/me resists temptation to point out that the libevent branch doesn't
compile with -Wall -Werror :-)

- if a callback function needs to be declared in a header, then having
a typedef can lead to #include noodle soup (it can also be argued that
callbacks should be static :-)

On the other hand, there's an evil trick to callback functions that
exploits the fact that structures have file (technically compilation
unit) scope.  Provided callback is static or of limited scope, you can
both strongly type the callback parameter and define its contents vis:


// header
void register_callback(void (*cb)(struct cb_context *context));


// file 1
struct cb_context {
  int c;
};
static void cb1(struct cb_context *context)
{
   printf("%d\n", context->c);
}
...
  register_callback(cb1);


// file 2
struct cb_context {
  float c;
};
static void cb2(struct cb_context *context)
{
   printf("%df\n", context->f);
}
...
  register_callback(cb2);

make that 1.4 cents

Andrew (who will now return to fixing testsuite and child-sa errors)

PS: 1.3 cents


More information about the Swan-dev mailing list