Conditions that cause Clang refuse inlining a function


I want to have some functions in my code inline so I use the inline keyword:

inline void foo() {}

On some functions the compiler inlines the function but it fails to do so on other functions and thus I get a linkage error:

error: undefined reference to ‘foo’

What are the conditions that make the compiler refuse inline?



p.s. I know that there are ways to pass compilation and let the compiler decide if to inline like using attribute((always_inline)) but I must have the function inline.


First of all, such a question definitely belongs to cfe-dev, not llvmdev.

Next, 'inline' is certainly a hint, and the full the answer is a first
entry here:

Hi Anton,
Thanks for the answer.

The link you provided doesn’t answer the question. It lists the ways to overcome the linking error if the inline was not successful.
The only condition that is found there to make the compiler not inline is “when compiling without optimization”.

I asked the question in the forum because I think that this info is not documented and most chances that the people that know the code inside-out will know the answer.


There are lots of reasons a compiler will choose not to inline a function (inlining, while usually a win for performance is a time/space tradeoff, so often a compiler will try not to make a function ‘too large’ by inlining too many functions into it - it will simply so at some threshold)

In any case, if the correctness of your program depends on the function being inlined, you can use the always_inline attribute.

C99 says that inline is just a hint. You can force the compiler to emit
an instance by adding a separate prototype without inline, i.e. "void
foo();" in one file. You can also specify static, in which case a local
(outlined) version is used.


Can these thresholds be customized with flags?
The always_inline attribute is only a hint and I can’t know if the compiler will actually do the inline or not.

Can these thresholds be customized with flags?

Not with any documented flags (ie: guaranteed to be around forever) I don't

The always_inline attribute is only a hint and I can't know if the
compiler will actually do the inline or not.

always_inline is more than a hint - the compiler makes pretty sure this
happens (even at -O0, etc, etc). About the only thing that can thwart this
is recursion (at which point it'd be impossible to inline). I'm not sure if
we have a warning to tell you about these cases.

There are many reasons:
- recursion
- varargs
- code size
- general unprofitability
- compiling with -O0

It sounds like you're having trouble with C99 inline. Make sure to have a
single .c file that redeclares the inline function without 'inline' like so:
// foo.h
inline int foo() { return 42; }
// foo.c
int foo();

The redeclaration will force the compiler to emit a strong definition in
that TU, preventing linkage errors, so long as you only do it in one TU.
See here for more info: