Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Some good reading material on this is Scott <s>Adams</s> Meyers' Effective C++ (Third Edition) Item 30: Understand the ins and outs of inlining, where he claims that a call to function pointer is never inlined. The third edition was published in 2008, and I have indeed been able to get gcc to inline function call by compile-time-constant-pointer starting in gcc 4.6, which came out in 2011 (maybe 2010?). However, this was in C and is tricky. In one scenario, I had to declare the calling function <code>__attribute__((flatten))</code> before it would inline the call (in this situation, I passed the function pointer as the member of a struct, who's pointer I then passed to an inline function that would make the function call by pointer that got inlined).</p> <p>So in short, no, this isn't a bug gcc, but that doesn't mean that gcc (and/or other compilers) might not be able to inline this some day. But the real issue, I think, is that you don't understand what's really happening here. To get that understanding, you have to think more like an assembly programmer, or a compiler programmer.</p> <p>You're passing an object of type <code>F&lt;X&gt;</code> and initializing it with a pointer to a member function of another class. You have not declared your instance <code>F&lt;X&gt;</code> object constant, it's <code>Func f_</code> member as constant, nor your <code>void F::operator()(T&amp; t)</code> member as constant. At the C++ language level, the compiler has to treat it as non-constant. That still doesn't mean that it can't later, at the optimization stage, determine that your function pointer doesn't change, but you're making it incredibly hard at this point. But at least it's a local. If your <code>F&lt;X&gt;</code> object had been global and not declared <code>static</code>, it would forbid it entirely from being considered constant.</p> <p>Hopefully, you're doing this on an exercise in inlining by function pointer and not as a real solution for indirection. When you want C++ to make real performance stuff, you use the power of types. Specifically, when I declare a template parameter as a member function pointer, it isn't just a constant, it's part of the type. I've never seen a case where this technique generates a function call.</p> <pre><code>#include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;algorithm&gt; #include &lt;ctime&gt; using namespace std; template &lt;typename T, void (T::*f_)()&gt; class F { public: void operator()(T&amp; t) { (t.*f_)(); } }; struct X { X() : x_(0) {} void f(){ ++x_; } int x_; }; int __attribute__((flatten)) main() { const int N = 100000000; vector&lt;X&gt; xv(N); auto begin = clock(); for_each (xv.begin(), xv.end(), F&lt;X, &amp;X::f&gt;()); auto end = clock(); cout &lt;&lt; end - begin &lt;&lt; endl; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload