Question

I used to think that the compiler decides whether to inline a function or not at compile time.

But then I found this code example in "Effective C++":

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

Now I'm confused, does that mean the decision whether to inline a function or not is done at run time, depending on how you use that function?

Was it helpful?

Solution

No, it's still done at compile time. In your example there are actually two versions of the function created by the compiler, one inline and one not.

Sometimes the compiler has enough information to know which function the pointer points to through static analysis, and can inline it anyway.

OTHER TIPS

Inlining is done at compile time or at link time (it seems compilers get to the point that they determine certain inlining possibilities at link time and do so across translation units).

The reason it isn't entirely clear whether pf() will result in inlining or not is that the compiler can potentially inline what pf points to if it can prove that pf will point to a certain function every time pf() gets called! In certain settings this can be done by determining the values based on constant expressions. For example:

void simple()
{
    void (*pf)() = f;
    pf();
}

It is relatively simple to prove that pf will always point to f. If f can be inlined that is safe to do. If things get more complex, e.g., some conditions or calls to other functions are involved, things get quickly sufficient complicated that the decision is certainly not easy any more.

Whether something is inline or not is part of code generation. That's the compiler's job. Ergo, inlining is done at compile time. But just because a function is inlined in some places, does not mean it must be inlined in all places. So it's perfectly okay for calls to f() to be inline, while calls to pf() are not.

Note, however, that if the compiler can prove, to itself, that pf will always be pointing to f at a particular point of invocation, then even that call can be inlined. I don't know whether or not any compilers go this far, but it is certainly allowed.

My understanding is that inlining is done at compile time. However there is a linker stage part to it also.

Inlining is a "Request" to a Compiler. Which can be ignored.

When: When the function is too complicated. Or when: Someone takes the address of the function (As the example you have given, is doing).

When someone takes the address of the function, then it means that the function has to occupy storage. And compiler does create the storage for it.

Then comes the issue of Inline functions being inside the header files which are included at many places. It should lead to "Multiple Definition" error" at linking time.

But in this situation the Linker is "Told to ignore" the multiple definitions.

Source: Thinking in C++, Page 434, Last Paragraph.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top