So this relatively straight-forward looking code fails to compile without optimisation:

#include inline void f1() { printf("In f1\n"); } inline void f2() { printf("In f2\n"); f1(); } void main() { printf("In main\n"); f2(); } Here's the linker error when compiled without optimisation:

% cc inline.c Undefined first referenced symbol in file f2 inline.o ld: fatal: Symbol referencing errors. No output written to a.out At low optimisation levels the compiler does not inline these functions, but because they are declared as inline functions the compiler does not generate function bodies for them - hence the linker error. To make the compiler generate the function bodies it is necessary to also declare them to be extern (this places them in every compilation unit, but the linker drops the duplicates). This can either be done by declaring them to be extern inline or by adding a second prototype. Both approaches are shown below:

#include extern inline void f1() { printf("In f1\n"); } inline void f2() { printf("In f2\n"); f1(); } extern void f2(); void main() { printf("In main\n"); f2(); } It might be tempting to copy the entire function body into a support file:

#include void f1() { printf("In duplicate f1\n"); } void f2() { printf("In duplicate f2\n"); f1(); } This is a bad idea, as you might gather from the deliberate difference I've made to the source code. Now you get different code depending on whether the compiler chooses to inline the functions or not. You can demonstrate this by compiling with and without optimisation, but this only forces the issue to appear. The compiler is free to choose whether to honour the inline directive or not, so the functions selected for inlining could vary from build to build. Here's a demonstration of the issue:

% cc -O inline.c inline2.c inline.c: inline2.c: % ./a.out In main In f2 In f1 % cc inline.c inline2.c inline.c: inline2.c: % ./a.out In main In duplicate f2 In duplicate f1 Douglas Walls goes into plenty of detail on the situation with inlining on his blog.



More...