3

When does the compiler necessarily not make a function marked inline as inline?

Niels Keurentjes
  • 41,402
  • 9
  • 98
  • 136
Nishanth
  • 317
  • 4
  • 16
  • For modern compilers, this might not be a binary choice. Modern compilers are known to split functions, and the decision to inline can be separate. E.g. since exceptions are assumed to be rare, compilers may inline only the non-exceptional part of a function. – MSalters Apr 16 '13 at 07:04

3 Answers3

2

Most obviously it can't inline the function when you take a pointer to the function. If you pass around the pointer and (maybe later) decide to call the function through the pointer, the compiler has to generate a non-inlined version of the function. Of course if the function is called directly, the compiler might still inline it. And the compiler is also free to not inline the function anyways.

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • +1 This is the fundamental reason functor-vs-funcptr provisions for things that can take either are more ideally suited for inline expansion given functors. An excellent Q&A on functors and their advantages can be found [in this question](http://stackoverflow.com/questions/356950/c-functors-and-their-uses). – WhozCraig Apr 15 '13 at 17:08
2

Using the inline keyword is merely a hint to the compiler that you suggest expanding it inline where used. The compiler is however far smarter than you will ever be at predicting what advanced CPU features such as the L1 and L2 caches, and branch prediction pipelines, might have as performance impact. If the compiler decides that inlining the function will make the code slower, or unacceptably larger, it will not inline it. Or, if it simply cannot because of a syntactical dependency, such as other code using a function pointer for callbacks, or exporting the function externally as in a dynamic/static code library.

See here for somewhat more explanation.

Niels Keurentjes
  • 41,402
  • 9
  • 98
  • 136
  • I don't think this has a lot to do with cache sizes. It mostly has to do with number of locals and efficient register allocation. – dtech Apr 15 '13 at 17:10
  • important to say - there is no way to know if it will plant the inline or not – Ariel Pinchover Apr 15 '13 at 17:11
  • @Infested - some compilers have intrinsics to force inlining – dtech Apr 15 '13 at 17:12
  • 1
    Cache size is most certainly relevant, inlining a function or not might cause the CPU to take different decisions in its caching strategy. It's not the most relevant factor admittedly, but it's one of the many things the compiler will try to keep in check. – Niels Keurentjes Apr 15 '13 at 17:14
  • @ddriver you are correct, but its not encouraged to write with this knowledge, as not all compilers do it. – Ariel Pinchover Apr 15 '13 at 17:14
0

If the question is when the compiler cannot by any means inline a function, there are a few answers.

When defined, a function that is recursive with a recursion level that depends on the arguments and not tail-recursive then it cannot be inlined (it is impossible to know at compile time how many iterations of the function there will be). In general, recursive functions that don't exhibit tail-recursion are not inlined (even in the cases where the compiler could infer the number of recursion steps).

When used through a pointer in a context where the pointer initialization is not seen.

If the question is not when is it guaranteed not to be inlined, but what things can make the compiler avoid inlining, there are some others. For example, the complexity and size of the function, whether it has loops, the level of inlining that it is already doing (f calls g calls h calls i... all of which could potentially be inlined, but compilers tend to give up if the number of calls is deep enough).... and there are others. You can try to find out from your compiler vendor what type of heuristics they run to determine when to inline.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489