Let me get this straight, in C99, for functions:
static
: Don't produce any external symbols
extern
(implicit): If there are no definitions in this translation unit, the compiler produces a reference that is resolved during linking
Now with inline
. As far as I can tell, the issue is complicated due to the fact that the compiler may choose to inline, or not.
I can see this being answered in two different ways:
static inline
seems to be the answer to #1:
static inline
function, then go for it. The static
storage specifier is consistent with its use with non-inline functions in that no external symbols are produced. Since this is the case, if the compiler decides to inline a static inline
function at every call site within a translation unit, it need not generate stand-alone object code.static inline
function at some call site, then it can generate stand-alone object code inside the translation unit, and no external symbols will be exported for it.As far as I can tell, extern inline
/inline
is the answer to #2:
inline
(without extern
or static
) behave like #2. If the compiler doesn't actually inline them, then at link time an external implementation needs to be linked-in.extern inline
. I think this is what's most
confusing, since the extern
keyword for normal functions behaves in
almost the exact opposite wayIs this correct?
Relevant links, yet still leave fuzzy corners:
Your overall understanding of this is correct.
The translation unit that actually exports a symbol to link against must declare as extern inline. I think this is what's most confusing, since the extern keyword for normal functions behaves in almost the exact opposite way
Yes, this is an unfortunate part of the language, but you have the right of it.
As a minor bit of trivia (which hopefully does not confuse you), GNU gcc used to treat "inline" and "extern inline" exactly opposite the way that the C99/C11 standard treats them. In this case, GNU would interpret "inline" as "use this definition to inline with AND produce the out-of-line, externally visible definition of this function" and it would treat "extern inline" as "only use this definition for inlining; if inlining does not occur, then emit an extern reference to the function (which must be defined elsewhere)".
For whatever reason the C99 standard chose to swap meaning of "inline" and "extern inline" and now we are stuck with it.
Note: Quick testing shows that GNU gcc v4.9.2 will default to the "GNU" way (-fgnu89-inline) if you don't otherwise pass -std=c99/c11 or -fno-gnu89-inline. Sometime between then and GNU gcc v5.2.1 it changed because v5.2.1 will default to -fno-gnu89-inline (i.e. the standard C99/C11 way).