Effective C++ item 30: Understand The Ins and Outs of Inlining

You may know inline keyword, which requests compiler to replace the function with it’s implementation in place to reduce funcion lookup time. Notice that I say request, not command. Compilers are free to use inline substitution for any function that’s not marked inline, and are free to generate function calls to any function marked inline. Compiler can choose to ignore your inline request for many reasons.

For example, calling a function through function pointer to an inline function most likely won’t be inlined.

1
2
3
4
5
inline void f() {...} // assume compilers are willing to inline calls to f
void (*pf)() = f; // pf points to f
f(); // this call will be inlined, because it's a "normal" call
pf(); // this call probably won't be, because it's through
// a function pointer

One misunderstanding lots of people have about inline is that templates must be inline. This is often based on the observation of oth inline and templates have to be in headers. In fact, they are independent of each other. The reason inline function has to be in header is in order for compiler to insert implementation into the place where this function is called, it has to know what’s the implementation. The reason template has to be defined in header is because compilers need to know what a template looks like in order to instantiate it when it’s used. Template instantiation is independent of inlining.

For inlining, compiler has the final call to either make it inline or not, unless you explicitly specify __attribute__((noinline)) or __attribute__((inline)) attributes. Consider following fucntion

1
2
3
template<typename T>
inline const T& foo(const T& a, const T& b)
{ ... }

1
2
3
template<typename T>
const T& foo(const T& a, const T& b)
{ ... }

They may result in the same machine code depending on what compiler decides. But you need to understand that the meaning of these two examples to programmers are different. The first function means please inline this function if possible. The second means don’t inline unless compiler decide to optimize.

The rule of thumb is don’t inline anything initially unless for speed optimization reason.

Reference:
“Effective C++” Third Edition by Scott Meyers.