(1) inline functions (from C++ Primer 3rd edition)
The keyword inline before the function return type in a function declaration or definition specifies min () as inline.
inline int min(int first, int secend) {/****/};
An inline function must be visible to the compiler so that it can expand the function within the call point. Unlike non-inline functions, inline functions must be defined in each text file that calls the function. Of course, for different files of the same program, the definition of the inline function must be the same if it appears. For a program made up of two files compute.C and draw.c, the programmer cannot define a min() function that refers to one thing in compute.C and another thing in draw.c. If the two definitions are different, the program will have undefined behavior.
To ensure that this does not happen, it is recommended to put the definition of the inline function in a header file. Include the header file in each file that calls the inline function. This ensures that there is only one definition for each inline function, the programmer does not have to copy the code, and it is impossible to cause unintentional mismatches during the lifetime of the program.
(2) The programming style of inline functions (from the High quality C++/C programming Guide)
The keyword inline must be placed with the body of the function definition to make the function inline, and simply putting inline before the function declaration does nothing.
A function Foo of the following style cannot be inline: inline void Foo(int x, int y); // Inline only with function declarations void Foo(int x, int y) {} While functions Foo(int x, int y) become inline functions: void Foo(int x, int y); Inline void Foo(int x, int y) // Inline goes with the body of the function definition {} So inline is a “keyword for implementation”, not a “keyword for declaration”. Generally, the user can read the declaration of the function, but not the definition of the function. Although inline is used in most textbooks before the declaration and definition body of an inline function, I don’t think inline should be used in a function declaration. This detail does not affect function functionality, but it illustrates a basic tenet of high-quality C++/C programming style: declaration and definition are not to be confused, and users do not need or should know whether functions need to be inlining.
Member functions defined in A class declaration automatically become inline functions, such as class A {public: Void Foo(int x, int y) {} // Foo(int x, int y) {} // Foo(int x, int y) {} // Foo(int x, int y) {} // Foo(int x, int y) {} // Foo(int x, int y) {} // Foo(int x, int y) {} Void Foo(int x, int y); } // Define file inline void A::Foo(int x, int y) {}
Inlining can improve the efficiency of function execution. Why not define all functions as inlining functions? If all functions were inline, would the keyword “inline” be necessary? Inlining is at the expense of code bloat (copy) and simply eliminates the overhead of function calls, thus improving the efficiency of function execution. If the time spent executing the code inside the function is large compared to the overhead of the function call, the efficiency gains will be small. On the other hand, copying code for every inline function call increases the total amount of code in the program and consumes more memory. Inlining should not be used in the following situations: (1) If the code in the function body is long, the use of inlining will lead to a high cost of memory consumption. (2) If there is a loop in the function body, then the time to execute the code in the function body is more expensive than the function call. Class constructors and destructors can be misleading as if using inline is more efficient. Be careful that constructors and destructors may hide some behavior, such as executing constructors and destructors of base classes or member objects “stealthily.” So don’t casually put the bodies of constructors and destructors in class declarations. A good compiler will automatically disable undesirable inline lines based on the body of the function definition (this further explains that inline should not appear in a function declaration).
C++ supports function inlining in order to improve the efficiency (speed) of function execution. In C programs, you can use macro code to improve execution efficiency. The macro code itself is not a function, but it acts like one. Preprocessors copy macro code instead of function calls, eliminating the need to push parameters, generate assembly language CALL calls, return parameters, and execute return, thus increasing speed. The biggest disadvantage of using macro code is that it is error-prone, and the preprocessor often produces unexpected marginal effects when copying macro code. With C++, using macro code has another disadvantage: you can’t manipulate the private data members of a class. Let’s see how C++ ‘s “function inlining” works. For any inline function, the compiler puts the declaration of the function (name, parameter type, return value type) in the symbol table. If the compiler finds no errors in the inline function, the code for that function is also put into the symbol table. When an inline function is called, the compiler first checks that the call was correct (for type safety, or for automatic type conversion, of course, for all functions). If correct, the code for the inline function replaces the function call directly, thus eliminating the overhead of the function call. This process is significantly different from preprocessing because the preprocessor cannot perform type safety checks or perform automatic type conversions. If the inline function were a member function, the object’s address (this) would be in place, which the preprocessor can’t. The function inlining mechanism of C++ has both the efficiency of macro code and increased security, and can freely manipulate the data members of the class. So in C++ programs, inline functions should replace all macro code, with the possible exception of “assert”. Assert is a macro that only works in the Debug version to check for things that “shouldn’t” happen. Assert should not cause any side effects in order not to cause a difference between the Debug and Release versions of your program. If assert is a function, the Debug version will differ from the Release version because of memory and code changes caused by function calls. So assert is not a function, it’s a macro.