title: Helping the compiler optimize function pointers
body: <p>A common way of implementing OO-like code encapsulation and polymorphism in C is to return opaque pointers to a structure containing some function pointers. This is a very frequent pattern for example in the Linux kernel.</p>
  
  <p>Using function pointers instead of function calls introduces an overhead which is mostly negligible due to caching, as has already been discussed in other questions.</p>
  
  <p>However, with the new -fwhole-program and -flto optimization options for GCC (>4.6), things change.</p>
  
  <h2>libPointers.c</h2>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include "libPointers.h"
  
  void do_work(struct worker *wrk, const int i) 
  {
          wrk-&gt;datum += i;
  }
  
  struct worker *libPointers_init(const int startDatum)
  {
          struct worker *wrk = malloc (sizeof (struct worker));
  
          *wrk = (struct worker) {
                  .do_work = do_work,
                  .datum = startDatum
          };
  
          return wrk;
  }
  </code></pre>
  
  <h2>libPointers.h</h2>
  
  <pre><code>#ifndef __LIBPOINTERS_H__
  #define __LIBPOINTERS_H__
  
  
  struct worker {
          int datum;
  
          void (*do_work)(struct worker *, int i);
  };
  
  extern void do_work (struct worker *elab, const int i);
  
  struct worker *libPointers_init(const int startDatum);
  
  
  #endif //__LIBPOINTERS_H__
  </code></pre>
  
  <h2>testPointers.c</h2>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include "libPointers.h"
  
  
  int main (void)
  {
          unsigned long i;
          struct worker *wrk;
  
          wrk = libPointers_init(56);
  
          for (i = 0; i &lt; 1e10; i++) {
  #ifdef USE_POINTERS
                  wrk-&gt;do_work(wrk,i);
  #else
                  do_work(wrk,i);
  #endif
          }
  
          printf ("%d\n", wrk-&gt;datum);
  }
  </code></pre>
  
  <p>Compiling with -O3, but without -flto -fwhole-program flags, testPointers execution takes around 25s on my machine, regardless whether USE_POINTERS is #defined or not.</p>
  
  <p>If I turn on the <strong>-flto -fwhole-program</strong> flags, testPointers takes around 25s with USE_POINTERS #defined, but around 14s if a function call is used.</p>
  
  <p>This is completely expected behavior, since I understand that the compiler will inline and optimize the function in the loop. I wonder, however, if there's a way of helping the compiler telling it that the function pointer is constant and so allowing it to optimize that case, too.</p>
  
  <p>For those using cmake, here's how I compiled it</p>
  
  <h2>CMakeLists.txt</h2>
  
  <pre><code>set (CMAKE_C_FLAGS "-O3 -fwhole-program -flto")
  #set (CMAKE_C_FLAGS "-O3")
  add_executable(testPointers
          libPointers.c
          testPointers.c
          )
  </code></pre>