6 * typesafe_cb - macros for safe callbacks.
8 * The basis of the typesafe_cb header is cast_if_type(): a
9 * conditional cast macro. If an expression exactly matches a given
10 * type, it is cast to the target type, otherwise it is left alone.
12 * This allows us to create functions which take a small number of
13 * specific types, rather than being forced to use a void *. In
14 * particular, it is useful for creating typesafe callbacks as the
15 * helpers typesafe_cb(), typesafe_cb_preargs() and
16 * typesafe_cb_postargs() demonstrate.
18 * The standard way of passing arguments to callback functions in C is
19 * to use a void pointer, which the callback then casts back to the
20 * expected type. This unfortunately subverts the type checking the
21 * compiler would perform if it were a direct call. Here's an example:
23 * static void my_callback(void *_obj)
25 * struct obj *obj = _obj;
29 * register_callback(my_callback, &my_obj);
31 * If we wanted to use the natural type for my_callback (ie. "void
32 * my_callback(struct obj *obj)"), we could make register_callback()
33 * take a void * as its first argument, but this would subvert all
34 * type checking. We really want register_callback() to accept only
35 * the exactly correct function type to match the argument, or a
36 * function which takes a void *.
38 * This is where typesafe_cb() comes in: it uses cast_if_type() to
39 * cast the callback function if it matches the argument type:
41 * void _register_callback(void (*cb)(void *arg), void *arg);
42 * #define register_callback(cb, arg) \
43 * _register_callback(typesafe_cb(void, (cb), (arg)), (arg))
45 * On compilers which don't support the extensions required
46 * cast_if_type() and friend become an unconditional cast, so your
47 * code will compile but you won't get type checking.
49 int main(int argc, char *argv[])
54 if (strcmp(argv[1], "depends") == 0) {