I defined my function in .c (without header declaration) as here:
inline int func(int i) {
return i+1;
}
Then in the same file below I use it:
...
i = func(i);
And during the linking I got "undefined reference to 'func'". Why?
The inline model in C99 is a bit different than most people think, and in particular different from the one used by C++
inline is only a hint such that the compiler doesn't complain about doubly defined symbols. It doesn't guarantee that a function is inlined, nor actually that a symbol is generated, if it is needed. To force the generation of a symbol you'd have to add a sort of instantiation after the inline definition:
int func(int i);
Usually you'd have the inline definition in a header file, that is then included in several .c files (compilation units). And you'd only have the above line in exactly one of the compilation units. You probably only see the problem that you have because you are not using optimization for your compiler run.
So, your use case of having the inline in the .c file doesn't make much sense, better just use static for that, even an additional inline doesn't buy you much.
C99 inline semantics are often misunderstood. The inline specifier serves two purposes:
First, as a compiler hint in case of static inline and extern inline declarations. Semantics remain unchanged if you remove the specifier.
Second, in case of raw inline (ie without static or 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.
This is particularly useful if you want to put a function into a shared library, but also make the function body available for optimization (eg inlining or specialization). Assuming a sufficiently smart compiler, this allows you to recover many of the benefits of C++ templates without having to jump through preprocessor hoops.
Note that it's a bit more messy than I described here as having another file scope non-inline external declaration will trigger the first case as described in Jens' answer, even if the definition itself is inline instead of extern inline. This is by design so you can have have a single inline definition in a header file, which you can include into the source file that provides the external one by adding a single line for the external declaration.
This is because of the way GCC handle inline function. GCC performs inline substitution as the part of optimization.
To remove this error use static before inline. Using static keyword force the compiler to inline this function, which makes the program compile successfully.
static inline int func(int i) {
return i+1;
}
...
i = func(i);
Related
I always though that the compiler can choose between inserting the function as is or to treat it as a regular function.
However I don't think it is possible if the inline function is defined in the header file (and can be included from multiple source files).
Is this correct?
Thanks
Yes, the compiler is completely free to chose if he really inlines an inline function. Actually he is free to inline any function, for which he has seen a definition.
inline as a keyword was introduced to avoid the "multiple symbol definition" problem. As such, it only makes sense if you have the definition in a header file.
The usual scheme is to have a definition like
inline void toto(void) {
...
}
in a header file that is included by several TU. Then in exactly one TU you have a declaration without inline
void toto(void);
which ensures that the symbol is exported by this TU.
In ISO C99 and ISO C11, having in the header file:
inline void f(void) { ..... }
means that the compiler can indeed choose between inlining the function, or treating it as a regular function.
However, when treating as a regular function, the compiler will behave similarly to if you had written void f(void);, i.e. it will expect to link to a body of f elsewhere.
So you need to put in exactly one of your translation units the line:
extern inline void f(void);
which causes the compiler to emit the body in that unit.
However, in GNU C, using inline void f(void) { ... } leads to undefined behaviour. The compiler can still choose, but when it chooses to treat as a regular function, it behaves as if you had written void f(void) { ... }, i.e. it emits the function body in every translation unit that uses it.
Some people write their functions in the header as static inline void f(void) { .... }, which works in both ISO C and GNU C, but possibly makes it harder for the linker to combine all of the copies into one.
See this thread for more detail
Assuming that an inline function is defined in a header like:
inline void f(void) {
...
}
...I can see two questions in your message, indeed:
Do you have to include that header with function definition in every
translation unit (TU) in which you are going to use this function?
Is the compiler free to inline the function in some TUs, while not
inlining it in other TUs, within the same project?
Ad.1: Short answer: Yes.
Long answer:
For compilation, definition (not only declaration!) of an inline function must be visible in every TU, where you are going to call it. Including the header in every TU is the best solution here.
By omitting the function’s storage class specifier in the header (as in the above code snippet, which is OK here, see below for short discussion on using extern or static), you go with the default, which means for inline functions: inline keyword is active in each TU in which you include this header. The function retains default external linkage (!), so it is also accessible from other TUs (i.e. in TUs not including this header), but the keyword inline is not active in the TUs that do not include functions’ inlined definition.
Now the linker must put a version of the function in some of the object files, so the function can be linked from the object files generated from TUs which do not include this functions’ ‘inline’ definition (or to the TUs where compiler decided not to inline despite the inline keyword).
You indicate that single TU by re-declaring the function as non-inlined, by adding after the included header file:
void f(void);
If you add static before your inline function definition in header, then each TU will generate its own copy and your executable code will probably take more space (subject to the zillion factors influencing code size with inlining). But you do not need to re-declare the function in any TU as non-inlined.
If you add extern to your inline function definition in header, then you will get ‘undefined reference’ linker error as none of TUs will generate executable code for it, despite possessing function’s definition (=knowing its body). To avoid it, at least one TU must additionally contain non-static re-declaration of this function:
inline void f(void);
(Note that GCC implements three different inlining semantics in C programs (GNU C90, gnu_inline, and one used e.g. with -std=c99), but to my knowledge none of them conforms to the above.)
Ad2: Yes. Even within a single TU the compiler is free to inline only a subset of calls to the inline function, or inline all calls, or none. Being honest, the same applies to functions defined without the inline keyword, because most compilers will try to ‘inline’, as part of their optimizations, even when the keyword is not used. After all, the keyword is just a hint to the compiler, as others have already highlighted in their comments/responses.
Consider the use of inline in C99, with various options (extern'ing, static inline etc), as described here, for example.
I don't understand why the C standard does not allow for just using
void inline foo() { do_stuff(); }
in a common header file, and for that to work everywhere. Why do I have to add static? Isn't what I want clear enough already?
From the gcc site:
When an inline function is not static, then the compiler must assume
that there may be calls from other source files; since a global symbol
can be defined only once in any program, the function must not be
defined in the other source files, so the calls therein cannot be
integrated. Therefore, a non-static inline function is always compiled
on its own in the usual fashion.
What does it mean for you. You cannot define the inline function in the header since it will mean that it will be defined from different translation units (.c files that include it).
Once it is defined static inline then each c file that includes the header will have its own copy of the function.
EDIT
gcc behaves correctly. Inline functions were added to the standard with the introduction of C99. The standard is somewhat ambiguous and states:
Any function with internal linkage can be an inline function. For a
function with external linkage, the following restrictions apply: If a
function is declared with an inline function specifier, then it shall
also be defined in the same translation unit. 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. An inline definition does
not provide an external definition for the function, and does not
forbid an external definition in another translation unit. An inline
definition provides an alternative to an external definition, which a
translator may use to implement any call to the function in the same
translation unit. It is unspecified whether a call to the function
uses the inline definition or the external definition.
What it actually means is that when the compiler sees the inline keyword cannot know if the function was already defined in another translation unit (This will be known only during linking). Now most compilers gcc included will not inline a function without optimizations turned on. So if you try to use an inline function when compiling with -O0 the compiler issues a real call to the function (It assumes it is defined in a another file then the one it is currently compiling). Now when the linker encounters the call it tries to find the function in all compiled objects but fails (because the compiler didn't create a body for the function neither did it inline it - the standard says it doesn't have to create a body for the function and that it can assume there is a definition some where). This is why you get the error: undefined reference to f when you link your project. This is the correct behavior when compiling with -std=c99 onward. It also means that if you want an inline function to have abody you must declare it external only once BUT you must also provide the definition within the same translation unit you declared the function with extrnal linkage.
So in order to get your code to work correctly according to the standard you should do the following:
in the h file just do as you would expect.
inline void f(){ /*DO SOMETHING*/}
And in just one of your code files (.c files) you do:
extern inline void f();
What happens is that now the compiler encounters in just one translation unit both body definition (taken from the header) and a declaration that says it should exist an external definition somewhere and in accordance with the standard creates one for the function.
So the standard says that any function with internal linkage can be declared inline and that the compiler should generate a body for it. In C a function is considered to have internal linkage only when adding the static keyword.
This is why static inline void f() works. Without the static keyword the compiler assumes that the function has external linkage and that is why just specifying inline void f() without also adding extern inline void f() in just one source file will not work.
...C standard does not allow for just using...
That's completely wrong. Your question is based on some incorrect/outdated/compiler specific premise, which has nothing to do with C standard. In C language you don't need static when putting inline function in header file. An inline definition without an explicitly specified extern keyword does not form an external definition for that function. For that reason inline definition without static cannot trigger any multiple-definition-related errors (if that's what you are afraid of).
Moreover, the link that you posted clearly says that C standard does not say anything implied in your question. It says that GCC compiler implements inline differently from what's required by C standard (probably referring to an older version of GCC).
In other words, from C language point of view you can (and should) put
inline void foo() { do_stuff(); }
in the header file. No static required.
I read several questions in stackoverflow about inline in C but still am not clear about it.
static inline void f(void) {} has no practical difference with static void f(void) {}.
inline void f(void) {} in C doesn't work as the C++ way. How does it work in C?
What actually does extern inline void f(void); do?
I never really found a use of the inline keyword in my C programs, and when I see this keyword in other people's code, it's almost always static inline, in which I see no difference with just static.
A C code can be optimized in two ways: For Code size and for Execution Time.
inline functions:
gcc.gnu.org says,
By declaring a function inline, you can direct GCC to make calls to that function faster. One way GCC can achieve this is to integrate that function's code into the code for its callers. This makes execution faster by eliminating the function-call overhead; in addition, if any of the actual argument values are constant, their known values may permit simplifications at compile time so that not all of the inline function's code needs to be included. The effect on code size is less predictable; object code may be larger or smaller with function inlining, depending on the particular case.
So, it tells the compiler to build the function into the code where it is used with the intention of improving execution time.
If you declare Small functions like setting/clearing a flag or some bit toggle which are performed repeatedly, inline, it can make a big performance difference with respect to time, but at the cost of code size.
non-static inline and Static inline
Again referring to gcc.gnu.org,
When an inline function is not static, then the compiler must assume that there may be calls from other source files; since a global symbol can be defined only once in any program, the function must not be defined in the other source files, so the calls therein cannot be integrated. Therefore, a non-static inline function is always compiled on its own in the usual fashion.
extern inline?
Again, gcc.gnu.org, says it all:
If you specify both inline and extern in the function definition, then the definition is used only for inlining. In no case is the function compiled on its own, not even if you refer to its address explicitly. Such an address becomes an external reference, as if you had only declared the function, and had not defined it.
This combination of inline and extern has almost the effect of a macro. The way to use it is to put a function definition in a header file with these keywords, and put another copy of the definition (lacking inline and extern) in a library file. The definition in the header file causes most calls to the function to be inlined. If any uses of the function remain, they refer to the single copy in the library.
To sum it up:
For inline void f(void){},
inline definition is only valid in the current translation unit.
For static inline void f(void) {}
Since the storage class is static, the identifier has internal linkage and the inline definition is invisible in other translation units.
For extern inline void f(void);
Since the storage class is extern, the identifier has external linkage and the inline definition also provides the external definition.
Note: when I talk about .c files and .h files in this answer, I assume you have laid out your code correctly, i.e. .c files only include .h files. The distinction is that a .h file may be included in multiple translation units.
static inline void f(void) {} has no practical difference with static void f(void) {}.
In ISO C, this is correct. They are identical in behaviour (assuming you don't re-declare them differently in the same TU of course!) the only practical effect may be to cause the compiler to optimize differently.
inline void f(void) {} in C doesn't work as the C++ way. How does it work in C? What actually does extern inline void f(void); do?
This is explained by this answer and also this thread.
In ISO C and C++, you can freely use inline void f(void) {} in header files -- although for different reasons!
In ISO C, it does not provide an external definition at all. In ISO C++ it does provide an external definition; however C++ has an additional rule (which C doesn't), that if there are multiple external definitions of an inline function, then the compiler sorts it out and picks one of them.
extern inline void f(void); in a .c file in ISO C is meant to be paired with the use of inline void f(void) {} in header files. It causes the external definition of the function to be emitted in that translation unit. If you don't do this then there is no external definition, and so you may get a link error (it is unspecified whether any particular call of f links to the external definition or not).
In other words, in ISO C you can manually select where the external definition goes; or suppress external definition entirely by using static inline everywhere; but in ISO C++ the compiler chooses if and where an external definition would go.
In GNU C, things are different (more on this below).
To complicate things further, GNU C++ allows you to write static inline an extern inline in C++ code... I wouldn't like to guess on what that does exactly
I never really found a use of the inline keyword in my C programs, and when I see this keyword in other people's code, it's almost always static inline
Many coders don't know what they're doing and just put together something that appears to work. Another factor here is that the code you're looking at might have been written for GNU C, not ISO C.
In GNU C, plain inline behaves differently to ISO C. It actually emits an externally visible definition, so having a .h file with a plain inline function included from two translation units causes undefined behaviour.
So if the coder wants to supply the inline optimization hint in GNU C, then static inline is required. Since static inline works in both ISO C and GNU C, it's natural that people ended up settling for that and seeing that it appeared to work without giving errors.
, in which I see no difference with just static.
The difference is just in the intent to provide a speed-over-size optimization hint to the compiler. With modern compilers this is superfluous.
From 6.7.4 Function specifiers in C11 specs
6 A function declared with an inline function specifier is an inline
function. Making a function an inline function suggests that calls to
the function be as fast as possible.138)The extent to which
such suggestions are effective is
implementation-defined.139)
138) By using, for example, an alternative to the usual function call
mechanism, such as inline substitution. Inline substitution is not
textual substitution, nor does it create a new function. Therefore,
for example, the expansion of a macro used within the body of the
function uses the definition it had at the point the function body
appears, and not where the function is called; and identifiers refer
to the declarations in scope where the body occurs. Likewise, the
function has a single address, regardless of the number of inline
definitions that occur in addition to the external
definition.
139) For example, an implementation might
never perform inline substitution, or might only perform inline
substitutions to calls in the scope of an inline declaration.
It suggests compiler that this function is widely used and requests to prefer speed in invocation of this function. But with modern intelligent compiler this may be more or less irrelevant as compilers can decide whether a function should be inlined and may ignore the inline request from users, because modern compilers can very effectively decide about how to invoke the functions.
static inline void f(void) {} has no practical difference with static
void f(void) {}.
So yes with modern compilers most of the time none. With any compilers there are no practical / observable output differences.
inline void f(void) {} in C doesn't work as the C++ way. How does it
work in C?
A function that is inline anywhere must be inline everywhere in C++ and linker does not complain multiple definition error (definition must be same).
What actually does extern inline void f(void); do?
This will provide external linkage to f. Because the f may be present in other compilation unit, a compiler may choose different call mechanism to speed up the calls or may ignore the inline completely.
A function where all the declarations (including the definition) mention inline and never extern.
There must be a definition in the same translation unit. The standard refers to this as an inline definition.
No stand-alone object code is emitted, so this definition can't be called from another translation unit.
In this example, all the declarations and definitions use inline but not extern:
// a declaration mentioning inline
inline int max(int a, int b);
// a definition mentioning inline
inline int max(int a, int b) {
return a > b ? a : b;
}
Here is a reference which can give you more clarity on the inline functions in C & also on the usage of inline & extern.
If you understand where they come from then you'll understand why they are there.
Both "inline" and "const" are C++ innovations that were eventually retrofit into C. One of the design goals implicit in these innovations, as well as later innovations, like template's and even lambda's, was to carve out the most common use-cases for the pre-processor (particularly, of "#define"), so as to minimize the use of and need for the pre-processor phase.
The occurrence of a pre-processor phase in a language severely limits the ability to provide transparency in the analysis of and translation from a language. This turned what ought to have been easy translation shell scripts into more complicated programs, such as "f2c" (Fortran to C) and the original C++ compiler "cfront" (C++ to C); and to a lesser degree, the "indent" utility. If you've ever had to deal with the translation output of convertors like these (and we have) or with actually making your own translators, then you'll know how much of an issue this is.
The "indent" utility, by the way, balks on the whole issue and just wings it, compromising by just treating macros calls as ordinary variables or function calls, and passing over "#include"'s. The issue will also arise with other tools that may want to do source-to-source conversion/translation, like automated re-engineering, re-coding and re-factoring tools; that is, things that more intelligently automate what you, the programmer, do.
So, the ideal is to reduce dependency on the pre-processor phase to a bare minimum. This is a goal that is good in its own right, independently of how the issue may have been encountered in the past.
Over time, as more and more of the use-cases became known and even standardized in their usage, they were encapsulated formally as language innovations.
One common use-case of "#define" to create manifest constants. To a large extent, this can now be handled be the "const" keyword and (in C++) "constexpr".
Another common use-case of "#define" is to create functions with macros. Much of this is now encapsulated by the "inline" function, and that's what it's meant to replace. The "lambda" construct takes this a step further, in C++.
Both "const" and "inline" were present in C++ from the time of its first external release - release E in February 1985. (We're the ones who transcribed and restored it. Before 2016, it only existed as a badly-clipped printout of several hundred pages.)
Other innovations were added later, like "template" in version 3.0 of cfront (having been accepted in the ANSI X3J16 meeting in 1990) and the lambda construct and "constexpr" much more recently.
As the word "Inline" say "In" "Line", adding this keyword to a function affects the program in runtime, when a program is compiled, the code written inside a function is pasted under the function call, as function calls are more costly than inline code, so this optimizes the code.
So, static inline void f(void) {} and static void f(void) {}, here the inline keyword does make a difference in runtime. But when the function has too many lines of code then it won't affect runtime.
If you add static before a function, the function's lifetime is the lifetime of the whole program. And that function use is restricted to that file only.
To know about extern you can refer to - Effects of the extern keyword on C functions
I'm trying to replace some macro subroutines with inline functions, so the compiler can optimize them, so the debugger can step into them, etc. If I define them as normal functions it works:
void do_something(void)
{
blah;
}
void main(void)
{
do_something();
}
but if I define them as inline:
inline void do_something(void)
{
blah;
}
void main(void)
{
do_something();
}
it says "Error: Undefined external". What does that mean? Taking a stab in the dark, I tried
static inline void do_something(void)
{
blah;
}
void main(void)
{
do_something();
}
and no more errors. The function definition and call to the function are in the same .c file.
Can someone explain why one works and the other doesn't?
(Second related question: Where do I put inline functions if I want to use them in more than one .c file?)
First, the compiler does not always inline functions marked as inline; eg if you turn all optimizations off it will probably not inline them.
When you define an inline function
inline void do_something(void)
{
blah
}
and use that function, even in the same file, the call to that function is resolved by the linker not the compiler, because it is implicitely "extern". But this definition alone does not provide an external definition of the function.
If you include a declaration without inline
void do_something(void);
in a C file which can see the inline definition, the compiler will provide an external definition of the function, and the error should go away.
The reason static inline works is that it makes the function visible only within that compilatioin unit, and so allows the compiler to resolve the call to the function (and optimize it) and emit the code for the function within that compilation unit. The linker then doesn't have to resolve it, so there is no need for an external definition.
The best place to put inline function is in a header file, and declare them static inline. This removes any need for an external definition, so it resolves the linker problem. However, this causes the compiler to emit the code for the function in every compilation unit that uses it, so could result in code bloat. But since the function is inline, it is probably small anyway, so this usually isn't a problem.
The other option is to define it as extern inline in the header, and in one C file provide and extern declaration without the inline modifier.
The gcc manual explains it thus:
By declaring a function inline, you can direct GCC to make calls to
that function faster. One way GCC can achieve this is to integrate
that function's code into the code for its callers. This makes
execution faster by eliminating the function-call overhead; in
addition, if any of the actual argument values are constant, their
known values may permit simplifications at compile time so that not
all of the inline function's code needs to be included. The effect on
code size is less predictable; object code may be larger or smaller
with function inlining, depending on the particular case. You can
also direct GCC to try to integrate all "simple enough" functions into
their callers with the option -finline-functions.
GCC implements three different semantics of declaring a function
inline. One is available with -std=gnu89 or -fgnu89-inline or
when gnu_inline attribute is present on all inline declarations,
another when -std=c99, -std=c1x, -std=gnu99 or -std=gnu1x
(without -fgnu89-inline), and the third is used when compiling C++.
To declare a function inline, use the inline keyword in its
declaration, like this:
static inline int
inc (int *a)
{
return (*a)++;
}
If you are writing a header file to be included in ISO C90 programs,
write __inline__ instead of inline.
The three types of inlining behave similarly in two important cases:
when the inline keyword is used on a static function, like the
example above, and when a function is first declared without using the
inline keyword and then is defined with inline, like this:
extern int inc (int *a);
inline int
inc (int *a)
{
return (*a)++;
}
In both of these common cases, the program behaves the same as if you
had not used the inline keyword, except for its speed.
When a function is both inline and static, if all calls to the
function are integrated into the caller, and the function's address is
never used, then the function's own assembler code is never
referenced. In this case, GCC does not actually output assembler code
for the function, unless you specify the option
-fkeep-inline-functions. Some calls cannot be integrated for various
reasons (in particular, calls that precede the function's definition
cannot be integrated, and neither can recursive calls within the
definition). If there is a nonintegrated call, then the function is
compiled to assembler code as usual. The function must also be
compiled as usual if the program refers to its address, because that
can't be inlined.
Note that certain usages in a function definition can make it
unsuitable for inline substitution. Among these usages are: use of
varargs, use of alloca, use of variable sized data types , use of computed goto,
use of nonlocal goto, and nested functions.
Using -Winline will warn when a function marked inline could not
be substituted, and will give the reason for the failure.
As required by ISO C++, GCC considers member functions defined within
the body of a class to be marked inline even if they are not
explicitly declared with the inline keyword. You can override this
with -fno-default-inline.
GCC does not inline any functions when not optimizing unless you
specify the always_inline attribute for the function, like this:
/* Prototype. */
inline void foo (const char) __attribute__((always_inline));
The remainder of this section is specific to GNU C90 inlining.
When an inline function is not static, then the compiler must
assume that there may be calls from other source files; since a global
symbol can be defined only once in any program, the function must not
be defined in the other source files, so the calls therein cannot be
integrated. Therefore, a non-static inline function is always
compiled on its own in the usual fashion.
If you specify both inline and extern in the function definition,
then the definition is used only for inlining. In no case is the
function compiled on its own, not even if you refer to its address
explicitly. Such an address becomes an external reference, as if you
had only declared the function, and had not defined it.
This combination of inline and extern has almost the effect of a
macro. The way to use it is to put a function definition in a header
file with these keywords, and put another copy of the definition
(lacking inline and extern) in a library file. The definition in
the header file will cause most calls to the function to be inlined.
If any uses of the function remain, they will refer to the single copy
in the library.
For inline functions to work with C99 (they only came there into the language) you'd have to give the definition in a header file
inline void do_something(void)
{
blah
}
and in one compilation unit (aka .c) you place some sort of "instantiation"
void do_something(void);
without the inline.
You have to put them in a header file if you want to use them from multiple files.
And for the linker error: the default declaration of a function implies that it's "extern", but since it's inlined, the linker can find the compiler-generated symbol stub, hence the error.
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.
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.
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.
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
In 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.
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:
make it a static inline function defintion.
Example:
// average.h
#ifndef AVERAGE_H
#define AVERAGE_H
static inline double average(double a, double b);
#endif
include the defintion from the c file and make it external.
Example:
#include "average.h"
extern double average(double a ,double b){
return (a + b) / 2;
}