_info.c 2.0 KB

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