I've always thought that the inline keyword is in C + +. Today I saw an article about the C language of the inline keyword. Oh...
It turns out I made a mistake. It seems that some macro commands can be replaced with some inline functions in the future. Here are the points I collected from the Internet (Source: http://superding.spaces.live.com/Blog/cns!89E842A8485366C7!1137.entry)
This article describes the differences in the use of inline in the GCC and C99 standards. The following two points should be noted when using the inline property:
The inline keyword is only described in the GCC reference document as being used on a function definition (definition), without mentioning whether it can be used for function declarations (Declare).
From the role of inline, it should also be useless in the function declaration: inline only affects the function in the translation unit (can be easily understood as a C source file) of the compilation behavior, as long as beyond the scope of the inline property does not have any effect. So the inline keyword should not appear in the function declaration, does not have any function to say, sometimes may also cause the compilation error (in the case that contains the Sys/compiler.h, the part that appears in the declaration of the inline keyword usually cannot be compiled through);
The inline keyword simply suggests that the compiler do inline expansion processing, not coercion. In the GCC compiler, if the compilation optimization is set to-o0, even the inline function is not expanded inline unless the Force inline () property is set __attribute__((always_inline))
.
1. The inline of GCC
GCC has made its own expansion of the C language, and its behavior differs greatly from the C99 standard.
1.1. Static inline
The static inline definition of GCC is easy to understand: you can think of it as a static function, plus the properties of inline. Most of this function behaves like a normal static function, except that when called, GCC expands its sink code at its invocation to compile without generating a separate assembly code for the function. In addition to the following situations:
When the address of the function is used. If the function is indirectly called through a function pointer. In this case, you have to generate a separate sink encoding for the static inline function, otherwise it does not have its own address.
Other things that cannot be unfolded, such as the behavior of the function itself, which recursively calls itself.
The static inline function, like the static function, defines a scope that is local, that is, you can have multiple definitions of the same name within a program (as long as it is not within the same file).
|
Attention |
The performance behavior of the static inline of GCC is consistent with the static inline of the C99 standard. So this definition can be used with ease and without compatibility issues. Points:
The static inline of GCC is only recommended for inline expansion of the compiler when invoked, relative to the static function;
GCC does not intentionally generate a separate sink encoding for the static inline function unless there is a situation where it must be generated (such as through function pointer invocation and recursive invocation);
The static inline function of GCC can only be used in file scope.
|
1.2. Inline
In contrast to C99 's inline, GCC's inline is easier to understand: it can be thought of as an ordinary global function plus inline properties. That is, in the file where its definition resides, its performance is consistent with static inline: It is compiled by inline when it can be expanded. But in order to be able to use it outside of the file, GCC will certainly generate a separate sink code for it to be called externally. From the outside of the file, it is the same as a normal extern function. As an example:
FOO.C:
/* This defines an inline function foo () */
inline Foo () {
...; The <-compiler generates a separate assembler code for foo () as a non-inline function
}
void Func1 () {
Foo (); <-in the same file Foo () may be compiled inline by the compiler instead of the assembly code generated above the direct call
}
When you call Foo () in another file, the assembly code generated in the above file is called directly:
BAR.C:
extern foo (); <-declare foo (), note that you cannot have the inline keyword within a declaration
void Func2 () {
Foo (); <-here is the assembler code generated by direct call for the Foo () function within FOO.C.
}
|
Important |
Although the behavior of the inline function of GCC is well understood, it differs greatly from the C99 's inline. Note the description of the C99 inline ( section 2.2, "inline") and how to use the inline function in a way that takes into consideration GCC and C99. Points:
The inline function of GCC suggests that the compiler do inline expansion in relation to the normal extern function only when it is called within the same file;
GCC is bound to generate a separate sink code for the inline function so that it is called outside of this file. In other files it appears that the inline function is the same as the normal extern function;
The inline function of GCC is global: it can be expanded inline as an inline function in a file, and it can be called outside the file.
|
1.3. extern inline
GCC's static inline and inline are well understood: it looks like you've added an inline property to a normal function. But this extern inline must not be taken for granted as an extern function +inline attribute. In fact, the extern inline of GCC is very strange: an extern inline function will only be inline, and will never generate a separate assembler code ! Even if a pointer is applied or a recursive call does not cause the compiler to generate a sink encoding for it, the call to this function is processed as an external reference. In addition, the extern inline function allows the same name as an external function, meaning that it is also legal to define an extern inline function with the same names in the presence of an externally defined global library function. The following examples specify the features of extern inline:
FOO.C:
[CPP]View Plaincopy
- extern inline
- int foo (int a)
- {&NBSP;&NBSP;
- return (-a);
- }&NBSP;&NBSP;
-
- void func1 ()
- {
- ...;
- a = foo (a); ①
- &NBSP;&NBSP;&NBSP;&NBSP;P_FOO&NBSP;=&NBSP;FOO;&NBSP;&NBSP;②&NBSP;&NBSP;
- b = p_foo (b); ③
- }&NBSP;&NBSP;
Within this file, GCC does not generate assembly codes for the Foo function. At the call point ① in Func1, the compiler will compile the Foo function defined here inline, which behaves like a normal inline function. Because such calls are capable of inline processing. At ②, the address of the Foo function is referenced. But note: The compiler will never generate a standalone sink code for an extern inline function! So in this case, the compiler has to handle it as an external reference, and link to the external Foo function (fill in the address of the external function) when the function address is not required. At this point, if the external does not define the global Foo function, then the link will produce an error that is not defined by the Foo function.
Suppose a global function foo is also defined in another file:
FOO2.C:
[CPP]View Plaincopy
- int foo (int a)
- {
- return (a);
- }
So in the example above, a reference to the Foo function address will be referred to the Foo function defined in the FOO2.C at the link. That is: The result of the ① call to the Foo function is a=-a because it is associated with the Foo function inside the foo.c, and the result of the ③ call is b=b, because it actually calls the Foo function in foo2.c!
The use of extern inline is very strange and seldom seen, but it has its practical value. First: It can act like a macro, you can replace the externally defined library function with the definition of an extern inline version within a file (provided that the call to it within the file does not appear to be inline); second: it allows a library function to be used inline as much as possible when it can be inline. As an example:
Within the C file of a library function, define a normal version of the library function Libfunc:
LIB.C:
void Libfunc ()
{
...;
}
And then in its header file, define (note not declaration!) ) A version that implements the same Exterin inline:
Lib.h:
extern inline Libfunc ()
{
...;
}
So when other files are going to use this library function, the compiler will use the extern inline version of the header file as long as the include Lib.h, where it can be expanded inline. In the case where it cannot be expanded (such as a function pointer reference), the compiler will refer to the LIB.C version of the standalone compilation. That looks like a function that can be inline externally, so this should be the origin of the extern inline meaning of gcc.
Note, however, that such use is costly: the implementation of the global function in the C file must be identical to the implementation of the extern-inline version within the header file. Otherwise, there will be an inconsistency in the performance of the functions shown in the previous example, directly inline and indirectly.
|
Important |
The use of the extern inline function of GCC is rather strange, and the scope of the application is very narrow: there is little that needs to be used. In C99, there is no description of extern inline, so it is not recommended to use extern inline unless you clearly understand the meaning of this usage and have plenty of reasons to use it! Points:
GCC will never generate a standalone sink code for extern inline functions
The extern inline function allows the same name as the global function, and can override externally defined global functions within the file scope
The extern inline function is very narrow in scope and behaves strangely, and is not recommended for use
|
2. C99 's Inline
The following mainly describes the different parts of C99 's inline and GCC. For the same section, refer to the GCC inline instructions.
2.1. Static inline
Static inline with GCC ( section 1.1, "static inline").
2.2. Inline
The use of C99 's inline is rather confusing. When a function that is defined as inline is not declared extern, it behaves somewhat like the extern inline in gcc (the C99 is a bit obscure in the text, as follows):
If all of the file scope declarations-a function in a translation unit include the inline
function specifier without , then the definition in this translation unit is an inline definition. An inline definition does not provide a 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 could use to implement any call T o The function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.
That is, if an inline function is not declared extern within the scope of the file, the function behaves in a file similar to the extern inline of GCC: When called in this file, the compiler is allowed to use the inline version defined in this file. But it also allows the external existence of global functions with the same name. It's just strange that C99 didn't specify whether the compiler had to use this inline version in this file, but rather vague definitions for the compiler manufacturer to decide for itself.
If the inline function is declared as extern in the file, the inline function behaves like the GCC inline: the function becomes a "external definition" (which can be understood as a global function): it can be called externally, And within the program there can be only one definition of such a name.
The following examples illustrate the features of inline in C99:
Inline double Fahr (double t)
{
Return (9.0 * t)/5.0 + 32.0;
}
Inline double cels (double t)
{
Return (5.0 * (t-32.0))/9.0;
}
extern double Fahr (double); ①
Double convert (int Is_fahr, double temp)
{
Return Is_fahr? Cels (temp): Fahr (temp); Ii
}
In the above example, the function Fahr is a global function: Because the Fahr is declared as extern at ①, it is necessary to use the version defined in this file when calling Fahr at ② (except that the compiler can inline the call here). This function can also be called outside the file (indicating that, like the inline of GCC, the compiler generates a separate assembler code for Fahr in this case).
The cels function, because it is not declared as extern in the file scope, is the "inline definition" mentioned earlier, when it can actually be used only in the scope of this file (just like a static function). Externally there may also be a global function with the same name as Cels. When calling Cels at ②, the compiler may choose to use the inline version within this file, or it may run to invoke an externally defined cels function (C99 does not specify the behavior at this point, but the compiler will definitely use the inline version defined in the file. Otherwise the inline function does not have any meaning.) From the performance here, the inline function that is not declared extern in C99 has been very similar to the extern inline of gcc: the inline function in this file can be used as an alternative to external library functions.
|
Important |
The behavior definition of the inline function in the C99 standard is ambiguous, and the inline function has no intrinsic difference in its representation that it is declared extern within the file scope. If compared to the inline function of GCC, an inline function declared extern is basically equivalent to the normal inline function of gcc, whereas an inline function that is not declared extern is basically equivalent to the gcc extern inline function . Because the inline function of C99 is so eccentric, it is recommended to create an extern declaration in the header file for all inline functions when used: Foo.h:
extern foo (); In the C file that defines the inline function, include this header file: FOO.C:
#include "foo.h"
inline void foo () { ...; } This results in the exact same result either with GCC's inline rules or C99: The Foo function is used inline within the foo.c file, and externally, it can be called directly like a normal global function. |
2.3. extern inline
C99 did not see the use of extern inline.
C-language inline keyword