From the C18 standard:
If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition.
Then we read:
The declaration of an inline function with external linkage can result in either an external definition, or a definition available for use only within the translation unit. A file scope declaration with extern creates an external definition.
I've written a bit of code to check if the function is actually inline or not. I've used this restriction to find out:
An inline definition of a function with external linkage shall not contain a definition of a modifiable object with static or thread storage duration, and shall not contain a reference to an identifier with internal linkage.
This is the code:
static int n = 5;
void inline foo() { n = 66; }
void inline foo(); // remove 'inline' in second version
int main() {
return 0;
}
When compiling this I get a warning saying that the inline function is using a static object, which means that foo()
is, effectively, an inline function, and so it provides an inline (not external) definition. However, when I remove the inline
specifier from the indicated line, I don't get the warning anymore. According to the standard, it's not an inline definition, so I guess it's providing an external definition.
What the standard is not saying, or at least I cannot see it, is whether an inline function that provides an external definition stops being an inline function, or not. According to my test, it does stop being an inline function.
If I'm right in my conclusions, which I don't know, another question arises: why an extern inline function is a useless thing?