Extern Vs Static Inline
This page describes how 'extern inline' is used in the kernel vs. 'static inline', and some of the tradeoffs involved.
At one point, the kernel could not function properly when you forced the compiler to not inline functions. There are functions in the kernel which do not work properly when they are expressed as functions (with function prolog and epilog code) rather than as inline code.
In 2001, Linus said:
- "static inline" means "we have to have this function, if you use it but don't inline it, then make a static version of it in this compilation unit" - "extern inline" means "I actually _have_ an extern for this function, but if you want to inline it, here's the inline-version" ... we should just convert all current users of "extern inline" to "static inline".
However, there are exceptions to this rule: For example http://www.uwsg.indiana.edu/hypermail/linux/kernel/0107.3/0519.html says:
[conversion from 'extern inline' to 'static inline'] Doesn't work for the ones in include/linux/parport_pc.h, which have extern versions in drivers/parport/parport_pc.c. Gives build errors.
See http://www.greenend.org.uk/rjk/2003/03/inline.html for a good discussion on inlining in GCC in general.
The following are some reasons to NOT change 'extern inline' to 'static inline' in order to preserve code correctness:
- if function pointers are taken for functions marked 'extern inline', then they will all be to the same function, and will match. However, if function pointers are takend for static inline functions, then they won't match and code which compares function addresses will behave differently.
- kernel developers sometimes use 'extern inline' to mark function which MUST not be inlined. Although the compiler may choose to not inline a function so marked, this rarely occurs in practice. By setting a function as 'extern inline', and then NOT providing as associated extern non-inline function to back it up, if the compiler fails to inline the function a linker error will be generated. This guarantees that the code will either run with the function inlined, or that it cannot be run at all.
So... when a kernel developer uses 'extern inline' without a backing extern function, it is an indication of a function that MUST be inlined.
There are other uses of 'extern inline' WITH backing extern functions (grep for EXTERN_INLINE - it will show up in the alpha architecture), but these are used for the traditional 'extern inline' reasons.