IMO both make the function to have a scope of the translation unit only.
What's the difference between "static" and "static inline" function?
Why should inline be put in a header file, not in .c file?
By default, an inline definition is only valid in the current translation unit.
If the storage class is extern, the identifier has external linkage and the inline definition also provides the external definition.
If the storage class is static, the identifier has internal linkage and the inline definition is invisible in other translation units.
If the storage class is unspecified, the inline definition is only visible in the current translation unit, but the identifier still has external linkage and an external definition must be provided in a different translation unit. The compiler is free to use either the inline or the external definition if the function is called within the current translation unit.
As the compiler is free to inline (and to not inline) any function whose definition is visible in the current translation unit (and, thanks to link-time optimizations, even in different translation units, though the C standard doesn't really account for that), for most practical purposes, there's no difference between static and static inline function definitions.
The inline specifier (like the register storage class) is only a compiler hint, and the compiler is free to completely ignore it. Standards-compliant non-optimizing compilers only have to honor their side-effects, and optimizing compilers will do these optimizations with or without explicit hints.
inline and register are not useless, though, as they instruct the compiler to throw errors when the programmer writes code that would make the optimizations impossible: An external inline definition can't reference identifiers with internal linkage (as these would be unavailable in a different translation unit) or define modifiable local variables with static storage duration (as these wouldn't share state accross translation units), and you can't take addresses of register-qualified variables.
Personally, I use the convention to mark static function definitions within headers also inline, as the main reason for putting function definitions in header files is to make them inlinable.
In general, I only use static inline function and static const object definitions in addition to extern declarations within headers.
I've never written an inline function with a storage class different from static.
static and static inline. Both of them make the definition invisible to other translation units. So what would be a sensible reason to write static inline instead of static?static inline expresses your intent/approval for it to be inlined, whereas static does not. To be clear about definitions, "semantics" is basically a fancy word for "meaning", and so that is the most essential semantic difference right there. Because source code is first and foremost about describing what you intend for the code to do. And if you proactively intend for inlining to happen, you should say so, and inline is the most "native" way to say so in the language of C.static inline and static INLINE_INTENT is that one of them also reveals your intent to compilers and other software (because we standardized on that as the way to express that specific intent).inline instructs the compiler to attempt to embed the function content into the calling code instead of executing an actual call.
For small functions that are called frequently that can make a big performance difference.
However, this is only a "hint", and the compiler may ignore it, and most compilers will try to "inline" even when the keyword is not used, as part of the optimizations, where its possible.
for example:
static int Inc(int i) {return i+1}; .... // some code int i; .... // some more code for (i=0; i<999999; i = Inc(i)) {/*do something here*/}; This tight loop will perform a function call on each iteration, and the function content is actually significantly less than the code the compiler needs to put to perform the call. inline will essentially instruct the compiler to convert the code above into an equivalent of:
int i; .... for (i=0; i<999999; i = i+1) { /* do something here */}; Skipping the actual function call and return
Obviously this is an example to show the point, not a real piece of code.
static refers to the scope. In C it means that the function/variable can only be used within the same translation unit.
static (with or without inline) can be in header perfectly well, see no reason why not. Templates is for C++, this question is about C.inline is good style, imo-O flag, or if -O0 is specified, the function call is still there. If you compile it with -O1 or above, now it is actually inlined, but even not specifying inline still inlines it, so there is no difference between static and static inline.inline doesn't instruct the compiler to do any attempts at inlining. It merely lets the programmer to include function body in multiple translation units without ODR violation. A side effect of this is that it's makes it possible for the compiler, when it would inline the function, to actually do this.From my experience with GCC I know that static and static inline differs in a way how compiler issue warnings about unused functions. More precisely when you declare static function and it isn't used in current translation unit then compiler produce warning about unused function, but you can inhibit that warning with changing it to static inline.
Thus I tend to think that static should be used in translation units and benefit from extra check compiler does to find unused functions. And static inline should be used in header files to provide functions that can be in-lined (due to absence of external linkage) without issuing warnings.
Unfortunately I cannot find any evidence for that logic. Even from GCC documentation I wasn't able to conclude that inline inhibits unused function warnings. I'd appreciate if someone will share links to description of that.
warning: unused function 'function' [clang-diagnostic-unused-function] for a static inline function when building withclang-tidy (v8.0.1), which is used in another translation unit. But definitely, this is one of the best explanations and reason for combining static & inline!One difference that's not at the language level but the popular implementation level: certain versions of gcc will remove unreferenced static inline functions from output by default, but will keep plain static functions even if unreferenced. I'm not sure which versions this applies to, but from a practical standpoint it means it may be a good idea to always use inline for static functions in headers.
inline in definition? Do you also imply not using it for extern functions?attribute((used)) and its use to allow asm to reference otherwise-unreferenced static functions and data.static and unused static inline functions over at godbolt.org. And they all warn about unused for static functions, but none warn for unused static inline. Also, unspecified storage class functions will remain if unused, without warning (even with optimizations). But I don't know how to test with headers on that site. (And I would get linker errors on anything above gcc 4.9.x when trying to compile with just inline.)In C, static means the function or variable you define can be only used in this file(i.e. the compile unit)
So, static inline means the inline function which can be used in this file only.
EDIT:
The compile unit should be The Translation Unit
the compile unit is something I wrote in error, there is no such thing, the actual terminology is translation unitIn C++, one important effect of inline (that is not mentioned in the other answers yet, I think) is that it prevents linker errors when multiple definitions of the function are found.
Consider a function that is defined in a header file to allow it to be inlined into the source files that include the header. If the compiler decides to not inline (all calls to) this function, the function definition will be included into every object file that references it (i.e. does not inline all calls).
This might cause multiple definitions of the functions to read the linker (though not always, since it depends on the inlining decisions made by the compiler). Without the inline keyword, this produces a linker error, but the inline keyword tells the linker to just pick one definition and discard the rest (which are expected to be equal, but this is not checked).
The static keyword, on the other hand, ensures that if a function is included in the object file, it will be private to that object file. If multiple object files contain the same function, they will coexist and all calls to the function will use their "own" version. This means that more memory is taken up. In practice, I believe this means that using static for functions defined in header files is not a good idea, better to just use inline.
In practice, this also means that static functions cannot produce linker errors, so the effect of inline above is not really useful for static functions. However, as suggested by ony in another answer, adding inline might be helpful to prevent warnings for unused functions.
Note that the above is true for C++. In C, inline works a bit different, and you have to explicitly put an extern declaration in a single source file to have the inline function emitted into that object file so it is available for any non-inlined uses. In other words, inline means that a function is not emitted into any source file, even when not all calls are inlined, unless it is also specified as extern, and then it is emitted (even if all local calls are inlined). I'm not sure how that interacts with static, though.
inline and C's.An inline definition is not externally linked.
// average.h #ifndef AVERAGE_H #define AVERAGE_H inline double average(double a, double b); #endif Attempting to call an inline function with the definition above from another module after it has been preprocessed or linked to a c file will result in an error.
There are two ways to solve this problem:
// average.h #ifndef AVERAGE_H #define AVERAGE_H static inline double average(double a, double b); #endif #include "average.h" extern double average(double a ,double b){ return (a + b) / 2; } inline definition in the header, otherwise you're defeating the purpose of declaring it inline. You do still need to instantiate an extern inline copy of the function in one compilation unit.
.hand theextern inlinedeclaration in exactly one.cto make a working C program with a non-staticinlinefunction defined in a header and thus able to actually inline. In C, should inline functions in headers be externed in the .c file? is also about that.