[C++] Detailed explanation of inline functions for C++ entry

foreword

We generally don't use macros in C++, and C++ recommends using:

  1. const enum to replace macro constants
  2. inline to replace macro functions


1. Why learn inline functions

Let's write a simple macro function independently before answering this question, write a macro Add() that adds two numbers

After writing, let's check the answer.
The correct way to write it is:

#define Add(x,y) ((x)+(y))

Don't underestimate such a simple question. Many people can't write a really usable macro. Even if they write it, they can't answer in detail: "Why do you need to add the first and second brackets?"

  1. The first parenthesis is to prevent bugs caused by operator precedence
    . For example:
Add(1,2)*3;

A bug occurs in the following code

#define Add(x,y) x + y

There will be no bugs under the following two codes

#define Add(x,y) (x + y)
#define Add(x,y) ((x)+(y))
  1. The second parenthesis is to prevent bugs because the parameters are expressions
    . For example:
Add(a|b,a&b);// a|b+a&b  //加号的优先级比位运算符高

A bug occurs in the following code

#define Add(x,y) (x + y)

In the following code, there will be no bugs

#define Add(x,y) ((x)+(y))

So macros are actually difficult to write well, and it is not conducive to debugging, but the advantage of macros is that they run quickly, and there is no need to create stack frames to save space and time. We want to inherit the advantages of macros and improve the shortcomings of macros. Then What should we do? That's right, the inline function in C++ is used to solve such problems.

Second, the use of inline functions

The use of inline functions is very simple. By adding keywords before the declaration or definition of the function and the return type of the function inline, the function can be designated as an inline function to improve the efficiency of program operation.
For example:

#include<iostream>
using namespace std;
inline int Add(int x, int y)
{
    
    
	int z = x + y;
	return z;
}
int main()
{
    
    
	int ret = Add(1,2);
	cout << ret << endl;
	return 0;
}

Let's take a look at the assembly code. We found that the call instruction did not appear when we called the Add function (the call instruction is a function call instruction), which shows that we did not create a stack frame when we used the Add function. It shows that it can indeed be the same as a macro, inlineno Create a stack frame to improve the efficiency of function operation.
insert image description here

Note: Because in debug mode, the compiler will not optimize the code by default, and the inline function will not work. You may want to see the assembly code after the inline function works in debug mode. The settings of vs2022 are given below Way)

Right-click the project,
insert image description here
click Properties
insert image description here
, set to program database (/Zi)
insert image description here
and click Optimize to select only suitable for _inline (/Ob1)
insert image description here

3. Characteristics of inline functions

  1. inlineIt is a practice of exchanging space for time. If the compiler treats the function as an inline function, it will replace the function call with the function body during the compilation phase .
    Disadvantage: It may increase the size of the target file. Advantage: Less call overhead and improve program operating efficiency.
  2. Inline is just a suggestion for the compiler. Different compilers may have different inline implementation mechanisms. The general suggestion is: make the function smaller (that is, the function is not very long, there is no exact statement, it depends on the internal implementation of the compiler), no Functions that are recursive and frequently called are inlinedecorated, otherwise the compiler ignores inlinethe feature. The following picture shows the suggestion of inline in the fifth edition of "C++prime":insert image description here

In general, the inlining mechanism is used to optimize small-scale, direct-flow, and frequently-called functions. Many compilers do not support inlining recursive functions, and a function with too many lines is unlikely to be expanded inline at the call site.

  1. Inline does not recommend separation of declaration and definition, which will lead to link errors. Because inline is expanded, there is no function address, and the link will not be found.
// test.h
#include <iostream>
using namespace std;
inline void f(int i);
// test.cpp
#include "test.h"
void f(int i)
{
    
    
	cout << i << endl;
}
// main.cpp
#include "test.h"
int main()
{
    
    
	f(10);
	return 0;
}
//报错误	C3861	“f”: 找不到标识符	

Inline functions are expanded during the compilation phase, unlike functions that form a symbol table and are linked during the linking phase.

correct spelling

// test.h
#include <iostream>
using namespace std;
inline void f(int i)
{
    
    
	cout << i << endl;
}
// main.cpp
#include "test.h"
int main()
{
    
    
	f(10);
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_65207641/article/details/128903278