Inline mechanisms and traps
The Inline mechanism is introduced with C ++ as an improvement and supplement to the macro (macro) mechanism (not a replacement ). The parameter transfer mechanism of inline functions is the same as that of common functions. However, the compiler expands the content of the inline function where each inline function is called. This avoids the overhead of function calls and does not have the first three defects of the macro mechanism.
HoweverProgramThe keyword "inline" in the Code is only a suggestion to the compiler: Functions modified by "inline" are not necessarily inline (but functions without "inline" modification must not ).
Many books will mention this because the compiler knows more about the overhead of function calls than most programmers, therefore, if the compiler considers that the overhead of calling a function is insignificant or insufficient to bear the consequences of code expansion, it is unnecessary to inline the function. This certainly makes sense. However, according to the style in which C and C ++ can give programmers full freedom and decision-making, the reason is not enough. I guess the main reason is to avoid endless recursion in the compiler. If recursive calls exist between inline functions, the compiler may encounter infinite recursion when expanding inline functions. Sometimes the recursive call of a function is very concealed, and it is not easy for programmers to discover it. For the sake of simplicity, let the compiler decide whether to inline or not.
Another way of not being inline is to use function pointers to call inline functions..
A common misunderstanding of the inline Mechanism in C ++ is that the keyword "inline" is only a suggestion to the compiler. If the compiler finds that the specified function is not suitable for inline, it will not be inline; therefore, no side effects will occur even if they are used improperly. This sentence is only half the correct one. Improper inline use may lead to side effects: Code expansion may occur, and difficult-to-find program bugs may be introduced.
According to the specification, when the compiler deems that the function to be inline is not suitable for inline, the compiler may not inline the function. However, if the function is not inline, it does not mean that the function is a common function. In terms of the actual implementation of the compiler, the inline failure function is different from the normal function:
(1) A common function is compiled with an object, which is included in the target file. When the target file is linked, the function call is linked to the object.
(2) If a function is declared as an inline function, the compiler will not compile an object for the function even if it encounters a declaration of the function, because the inline function is expanded where it is used. But what if I find that this inline function is not suitable for expansion when I call this inline function? One option is to compile an object for this inline function in the target file that calls this inline function. The direct consequence of this is that if a function that fails to be inline is called in multiple files, the target file corresponding to each file will contain the target code of this inline function.
If the compiler really chooses the above practice to treat the function that fails inline, then the best situation is: the mutton is not eaten, and it is a cool. That is, the benefits of inline are not enjoyed, but the disadvantages are borne: the size of the target Code expands like that of the target code that is successfully inline, but the efficiency of the target code is indeed the same as that of the non-Inline code.
Worse, there are multiple function target codes that bring some program bugs. The most obvious example is that the static variables in the function that fails inline are not only one copy, but several copies. This is obviously a mistake, but it is difficult to find the cause if you do not understand the details.