]> git.ozlabs.org Git - ccan/blob - ccan/typesafe_cb/_info.c
Fix warnings for isaac w/ gcc4.1.
[ccan] / ccan / typesafe_cb / _info.c
1 #include <stdio.h>
2 #include <string.h>
3 #include "config.h"
4
5 /**
6  * typesafe_cb - macros for safe callbacks.
7  *
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.
11  *
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.
17  * 
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:
22  *
23  *      static void my_callback(void *_obj)
24  *      {
25  *              struct obj *obj = _obj;
26  *              ...
27  *      }
28  *      ...
29  *              register_callback(my_callback, &my_obj);
30  *
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 *.
37  *
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:
40  *
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))
44  *
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.
48  *
49  * Licence: LGPL (2 or any later version)
50  */
51 int main(int argc, char *argv[])
52 {
53         if (argc != 2)
54                 return 1;
55
56         if (strcmp(argv[1], "depends") == 0) {
57                 return 0;
58         }
59
60         return 1;
61 }