C99 inline semantics are often misunderstood. The inline specifier serves two purposes:
First, as a compiler hint in case of
extern inlinedeclarations. Semantics remain unchanged if you remove the specifier.
Second, in case of raw inline (ie without
extern) to provide an inline definition as an alternative to an external one, which has to be present in a different translation unit. Not providing the external one is undefined behaviour, which will normally manifest as linking failure.
static inline === static
extern inline === extern
inline === extern