title: Is it a good idea to put user-definable types into callback prototypes?
body: <p>In order to improve type safety in some C library code, I got the idea to use user-definable types in callback functions. So instead of carrying a <code>void*</code> around, the code uses a <code>Usertype*</code>. The library does only declare the type, but not define it, and uses this type as an opaque pointer. Instead of the regular scheme, that a library defines all used types, the parts which are used in callback functions are forward declared, and left to be defined by the user.</p>
  
  <pre><code>/*library code*/
  
  struct UserDataForFooCallback; /* opaque user datatype */
  
  typedef void CallbackFn(int i, struct UserDataForFooCallback* user);
  
  void foo(CallbackFn* callback, struct UserDataForFooCallback* user)
  {
      callback(42, user);
  }
  
  
  /*application code*/
  
  #include &lt;stdio.h&gt;
  #include "foo.h"
  
  struct UserDataForFooCallback
  {
      int a;
  };
  
  static void fooCallback(int i, struct UserDataForFooCallback* user)
  {
      printf(user-&gt;a == i ? "ok\n" : "fail\n");
  }
  
  int main()
  {
      struct UserDataForFooCallback cbd = {42};
      foo(fooCallback, &amp;cbd);
      return 0;
  }
  </code></pre>
  
  <p>Advantages:</p>
  
  <ul>
  <li>Type safe callbacks</li>
  <li>no <code>struct MyFoo* data=arg</code> pointer assignments in the callback code</li>
  </ul>
  
  <p>Drawbacks:</p>
  
  <ul>
  <li>AFAIK there must not be more than one definition of a user defined datatype (or am I mixing this with the one definition rule of C++?), which makes them problematic if there are more than uses of the back-calling function (say <code>foo</code> in the example is used by different program parts)</li>
  <li>The need to define a new type for every callback/group of callbacks (maybe it's not so important, since the many callback functions does use one already)</li>
  </ul>
  
  <p>The main thing I want to know if this is really a good idea, or if thie is only a good-looking-but-Armageddon-like-impact idea.</p>