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
.
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.
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With