You're saying that "function definitions should go to translation units"... yes, but an inline function is such that it is supposed to be inlinable in another translation unit. And the C compilers commonly do not look for code to inline from other translation units, but they just compile separate translation units into separate object files and only the linker would see the program in its entirety.
Back in times the solution for this would be to define a function in a header file with static
(note it is a definition in a header file!), and hope that the compiler would be smart enough to inline the function. But a stupid compiler would generate a separate static function in each translation unit, and not inline anything, leading to both bad performance and wasted memory.
Now with inline
and extern inline
it means that a function defined as inline foo
is supposed to be the same function throughout the program - you can take the function pointer of it in any translation unit and you will get the same function pointer.
Anywhere you see inline void foo(int bar) { ... }
it is equally a function definition. But only in one translation unit in the entire program would there be extern inline void foo(int bar);
that would cause the function with external linkage to appear in that file. This has a nice property in that it makes legacy tool chains (linkers etc) be able to completely ignore the inline keyword behaviour, they just see that there is one symbol foo
for a function in that one object file.
Finally, you're not required to have the same function definition as the externally defined one - it can be a different one - just do not include the inline
function definition from the header but define a completely different one, for example
inline int foo(void) {
puts("Hello from an inlined function");
}
extern inline int foo(void) {
puts("Hello from an external function using a completely different algorithm"
" here that results in more code bloat but offsets the fact that the"
" function call to this definition was not inlined");
}
But it is nice that the C allows you to have the same definition without repeating yourself!