tags:

views:

219

answers:

7

Inline functions are just a request to compilers that insert the complete body of the inline function in every place in the code where that function is used.

But how the compiler decides whether it should insert it or not? Which algorithm/mechanism it uses to decide?

Thanks,

Naveen

A: 

it inserts if you write "inline" to beginning of the function?

ufukgun
Need not be. Its just a request.
Naveen
For C++ it basically only means that it does not cause linker-errors if different object files contain the same definition. That's required by the standard. Using `inline` or not is usually not correlated in any way whether the function really gets inlined.
gimpf
at least comments inform people :)
ufukgun
+2  A: 

All I know about inline functions (and a lot of other c++ stuff) is here.

Also, if you're focusing on the heuristics of each compiler to decide wether or not inlie a function, that's implementation dependant and you should look at each compiler's documentation. Keep in mind that the heuristic could also change depending on the level of optimitation.

yeyeyerman
+1  A: 

I'm pretty sure most compilers decide based on the length of the function (when compiled) in bytes and how often it is used vs the optimization type (speed vs size).

Blindy
+1  A: 

I know only couple criteria:

  • If inline meets recursion - inline will be ignored.
  • switch/while/for in most cases cause compiler to ignore inline
Dewfy
+1  A: 

It depends on the compiler. Here's (the first part of) what the GCC manual says:

    -finline-limit=n
           By default, GCC limits the size of functions that can be inlined.
           This flag allows the control of this limit for functions that are
           explicitly marked as inline (i.e., marked with the inline keyword
           or defined within the class definition in c++).  n is the size of
           functions that can be inlined in number of pseudo instructions (not
           counting parameter handling).  The default value of n is 600.
           Increasing this value can result in more inlined code at the cost
           of compilation time and memory consumption.  Decreasing usually
           makes the compilation faster and less code will be inlined (which
           presumably means slower programs).  This option is particularly
           useful for programs that use inlining heavily such as those based
           on recursive templates with C++.

           Inlining is actually controlled by a number of parameters, which
           may be specified individually by using --param name=value.  The
           -finline-limit=n option sets some of these parameters as follows:

            @item max-inline-insns-single
             is set to I/2.
            @item max-inline-insns-auto
             is set to I/2.
            @item min-inline-insns
             is set to 130 or I/4, whichever is smaller.
            @item max-inline-insns-rtl
             is set to I.

           See below for a documentation of the individual parameters
           controlling inlining.

           Note: pseudo instruction represents, in this particular context, an
           abstract measurement of function's size.  In no way, it represents
           a count of assembly instructions and as such its exact meaning
           might change from one release to an another.
Steve Jessop
+2  A: 

Some common aspects:

  • Compiler option (debug builds usually don't inline, or oyu can tell your compiler to inline regardless of the delcaration)
  • suitable calling convention (varargs usually functions aren't inlined)
  • suitable for inlining: depends on size of the function, frequency of the funciton, and optimization settings (speed vs. code size). E.g. a huge function may be inlined if it is called just once
  • inline call depth and recursion

The 3rd is probably the core of your question, but that's really "compiler specific heuristics" - you need to check the compiler docs, but usualyl they won't give much guarantees. MSDN has some (limited) information for MSVC.

Beyond trivialities (e.g. simple getters and very primitive functions), inlining as such isn't very helpful anymore. The cost of the call instruction has gone down, and branch prediction has greatly improved.

The great opportunity for inlining is removing code paths that the compiler knows won't be taken - as an extreme example:

inline int Foo(bool refresh = false)
{
   if (refresh)
   {
      // ...extensive code to update m_foo  
   }
   return m_foo;
}

A good compiler would inline Foo(false), but not Foo(true).

With Link Time Code Generation, Foo could reside in a .cpp (without a inline declararion), and Foo(false) would still be inlined, so again inline has only marginal effects here.


To summarize: There are few scenarios where you should attempt to take manual control of inlining by placing (or omitting) inline statements.

peterchen
+2  A: 

The following is in the FAQ for the Sun Studio 11 compiler:

The compiler generates an inline function as an ordinary callable function (out of line) when any of the following is true:

  • You compile with +d.
  • You compile with -g.
  • The function's address is needed (as with a virtual function).
  • The function contains control structures the compiler can't generate inline.
  • The function is too complex.

According to the response to this post by 'clamage45' the "control structures that the compiler can't generate inline" are:

  • the function contains forbidden constructs, like loop, switch, or goto

Another list can be found here. As most other answers have specified the heuristics are going to be 100% compiler specific, from what I've read I think to ensure that a function is actually inlined you need to avoid:

  • local static variables
  • loop constructs
  • switch statements
  • try/catch
  • goto
  • recursion
  • and of course too complex (whatever that means)
Richard Corden