[C++] How do you use inline functions (inline)?

Foreword:

        This article will introduce what are inline functions, the difference between inline functions and ordinary functions, the defects of preprocessing macros, the advantages and disadvantages of inline functions, and some tips for using inline functions. I hope that after reading this blog, readers can have a deeper understanding of inline functions (inline).

1. What is an inline function

        Inline function is a technique to reduce function call overhead by expanding the function body. It can be understood as embedding the function body of other function calls directly into the call place, which saves the overhead of parameter passing, suspension and return when calling , thereby improving the execution efficiency of the program. In C++, you can use the inline keyword to declare an inline function.

Here's how to define an inline function:

inline 函数返回类型 函数名(参数列表)
{
    函数体
}

For example, we define an inline function that calculates the sum of two integers:

inline int Sum(int a, int b)
{
    return a + b;
}

Inline functions inside a class:

         In order to define an inline function, it is usually necessary to precede the function definition with the inline keyword. But it is not necessary to define an inline function inside a class. Any function defined inside a class automatically becomes an inline function .

class Person {
public:
  void PrintInfo() {  // 在类内部定义的函数默认为内联函数
    cout << "This is a person." << endl;
  }
};

2. Inline functions, ordinary functions and preprocessing macros

1. The difference between inline functions and ordinary functions:

        Although the functions of inline functions and ordinary functions are the same, there are still some differences between them.

1) The function body of an inline function is shorter than that of an ordinary function

        This is because the inline function will be expanded at the call site. If the function body is too long, the expanded code will be very long, which will increase the code size and reduce maintainability.

2) Inline functions will be replaced at compile time, while ordinary functions need to be called at runtime

        Therefore, inline functions execute faster than ordinary functions. However, if the inline function is called frequently, it may have a certain impact on the size of the code, because each call will generate the corresponding code.

3) Inline functions do not allow recursive calls

        This is because the expansion of the inline function is determined at compile time, and the recursive call needs to be performed when the program is running, and the two are not compatible.

2. Defects of preprocessing macros:

        Preprocessing macros can replace function calls in some cases, but there are some problems with preprocessing macros, which may bring some potential risks and adverse effects to the program. Specifically, preprocessing macros have the following drawbacks:

1) Lack of type checking and scoping

        Preprocessing macros perform text replacement in the preprocessing stage, and it does not have the functions of type checking and scope. This means that preprocessing macros may introduce some type errors and scope problems, making it more difficult to debug the program.

#include <iostream>
#define MULTIPLY(a,b) a*b

using namespace std;

inline int multiply(int a, int b) {
    return a * b;
}

int main()
{
    int i = 3, j = 4, x,y;
    x = MULTIPLY(i + 1, j + 1); // 预处理宏展开式为i+1*j+1 结果:8
    y = multiply(i + 1, j + 1); // 内联函数  结果:20
    cout << "The value of x is: " << x << endl;
    cout << "The value of y is: " << y << endl;
    return 0;
}

2) It is easy to cause side effects

        The replacement of preprocessing macros is carried out in the preprocessing stage, and the side effects that may be caused during program execution will not be considered. If complex operations are performed in the macro definition, it may cause some unexpected results, increasing the difficulty and uncertainty of the program.

#include <iostream>
#define MAX(a,b) a > b ? a++ : b++

using namespace std;

inline int max(int a, int b) {
    return a > b ? a++: b++;
}

int main()
{
    int x = 2, y = 2;
    //int m = MAX(++x, y); // 宏展开式为++x > y ? ++x++ : y++
    int xx = 2, yy = 2; 
    int n = max(++xx, yy); //内联函数结果:3
    //cout << "The value of m is: " << m << endl;
    cout << "The value of n is: " << n << endl;
  
    return 0;
}

3) Poor readability

        The code expansion after preprocessing macro replacement is usually long and difficult to read and understand. This will increase the maintenance difficulty and scalability of the program.

#include <iostream>
#define SQUARE(x) x*x

using namespace std;
inline int square(int x) {
    return x * x;
}

int main()
{
    int i = 2, j;
    j = SQUARE(SQUARE(i + 1)); // 预处理宏展结果:9
    cout << "The value of j is: " << j << endl;
    j = square(square(i + 1)); //内联函数结果:81
    cout << "The value of j is: " << j << endl;
    return 0;
}

Third, the advantages and disadvantages of inline functions

1. Advantages:

1) Reduce the overhead of function calls

        The inline function is directly expanded when called, avoiding the overhead of parameter passing, suspending and returning, thereby improving the execution efficiency of the program.

2) Enhance code readability

        The inline function will replace the function body with the call site, which can avoid inserting useless function calls in the middle, thereby reducing the number of code lines, reducing the complexity of the code, and enhancing the readability of the code.

2. Disadvantages:

1) Increased the size of the code

        Although the advantage of inline functions is that it saves the time of function calls, but each call will generate corresponding code, which will increase the size of the code.

2) Excessive use can lead to code performance degradation

        There is a limit on the size of the expansion in an inline function. If the function body is too long, the amount of code for each call to the expansion will be large, thereby reducing the performance of the program.

4. Compiler decides to inline functions

        Inline functions and the compiler are inseparable. Only with the support of the compiler, the inline function can really play its advantages and improve the execution efficiency of the program.

        When the compiler processes the source code, it will expand the function definition of the inline function to the calling site, thereby converting the function call into a direct call to the function body, avoiding the overhead of parameter passing, suspension and return when the function is called, Thus, the execution efficiency of the program is improved. At the same time, because the expansion of the inline function has replaced the function call statement, the overhead of the function call will not be generated when the program is executed, thereby reducing the running time of the program.

        It is important to note that inline functions do not work best in all cases. The reason why the compiler can expand and replace the inline function is because the compiler can optimize the program, analyze the program structure, and replace the function call with a direct call. But in some cases, the compiler may have difficulty optimizing the program, so inlining functions may not be the best choice. For example, if the function body of the inline function is too large, it may cause the generated code to be too long after expansion, thereby increasing the program size and degrading the performance of the program.

In addition, c++ inline compilation has some restrictions. The compiler may consider not to inline compile the function in the following cases:

  • There cannot be loop statements of any kind
  • There cannot be too many conditional judgment statements
  • The function body should not be too large
  • Cannot take address of function

        Inlining is just a suggestion to the compiler, and the compiler may not accept this suggestion. If you do not declare the function as an inline function, the compiler may also compile the function inline. A good compiler will inline small, simple functions.

        Therefore, when using inline functions, you need to choose according to the specific situation and needs to achieve the best effect. The balance between variation and efficiency of inline functions needs to be considered , as well as compiler support and constraints . Only with the support of the compiler, the inline function can really play its advantages and improve the operating efficiency of the program.        

5. Some tips for using inline functions

Here are some tips for using inline functions:

1. The function body is small

        Normally, the function body of an inline function should be small, because the expansion directly replaces the statement at the call site. If the function body is too large, the expansion may be very long, which increases the amount of code.

For example, the following defines a simple inline function that compares the magnitudes of two values:

inline int Max(int a, int b)
{
    return a > b ? a : b;
}

2. The function is called frequently

        For frequently called functions, it can be defined as an inline function. Doing so can avoid the overhead of function calls and improve the execution efficiency of the program.

For example, the following inline function is used to convert a string to uppercase:

inline void ToUpperCase(string& str)
{
    transform(str.begin(), str.end(), str.begin(), ::toupper);
}

3. The return value type of the function is a constant expression

        For a function whose return value type is a constant expression, it can be defined as an inline function. Doing so reduces the overhead of function calls and returns.

For example, the following inline function calculates the product of two numbers:

inline constexpr int Multiply(int a, int b)
{
    return a * b;
}

        It should be noted that when using inline functions, the choice should be made according to the actual situation. If the function body is relatively large, or the function is not called frequently, defining it as an inline function may reduce the performance of the program. In addition, inline functions are not suitable for recursive calls, because repeated expansion may cause the program to occupy a large amount of stack space.

Summarize:

        Although the use of inline functions can improve the execution efficiency of the program, attention should be paid to the size of the expansion of the inline function and whether it has the characteristics of being frequently called. It needs to be selected according to the specific situation and needs in order to achieve the best effect.

Guess you like

Origin blog.csdn.net/crr411422/article/details/130984884