title: Function pointer to function macro
body: <p>Good morning,</p>
  
  <p>I am trying to write in C a dynamic array that can accept different types. </p>
  
  <p>The main structure is built as follows:</p>
  
  <pre><code>typedef struct st_array
  {
     void* array;
     uint16_t size;
     uint16_t used;
  
     void  ( *push )( struct st_array*, void* );
     void* ( *at   )( struct st_array*, uint16_t );
  } st_array;
  
  void pushInArray( st_array* this, void* item )
  {
      // Check for last occupied bin
      // if equal size, realloc() and increase this-&gt;size
      this-&gt;array[this-&gt;used++] = item;
  }
  
  void* getAt( st_array* this, utf16_t idx )
  {
      if( idx &lt;= this-&gt;used )
          return this-&gt;array[idx];
      return NULL;
  }
  
  st_array NewArray( uint16_t size )
  {
      st_array this;
      this.array = malloc( size * sizeof( void* ) );
  
      this.push = &amp;pushInArray;
      this.at = &amp;getAt;
      ...
      return this;
   }
  </code></pre>
  
  <p>In order to use this, I need to cast for my variable type at each call of <code>push()</code> and <code>at()</code>:</p>
  
  <pre><code>int item = 13;
  st_array a = NewArray( 32 );
  a.push( &amp;a, (void*)&amp;item );
  
  int item_ret = *(int*)a.at( &amp;a, 0 );
  </code></pre>
  
  <p>I'd prefer to avoid the casting (although it can be useful, just to keep the programmer aware of what is she doing).
  It is possible to define a function-style macro that accept the type as parameter, but I still have to figure out how to "bind" it to the structure function pointer.</p>
  
  <p>I imagine the simplest solution might just be defining a function-style macro as (now written without checks to keep it short):</p>
  
  <pre><code>#define push( a, b ) a-&gt;array[a-&gt;used++] = ( void* )b
  #define get( a, i, t ) *(t*)a-&gt;array[i]
  </code></pre>
  
  <p>and using them as:</p>
  
  <pre><code>push( &amp;a, &amp;item );
  int item_ret = get( &amp;a, 0, int );
  </code></pre>
  
  <p>but I'm not that sure on how to proceed. Can somebody please give me some advice?</p>