Inline functions have the structure of functions from the source code level, but after compilation, they do not have the properties of functions. During compilation, similar to macro replacement, the function body is used to replace the function name at the call site. Generally, the inline modifier is used in the code, but whether an inline function can be formed depends on the specific processing of the compiler on the function definition.
motivation
Inline expansion is used to eliminate the time overhead of a function call. It is usually used for frequently executed functions. A small memory footprint is a great benefit for functions. Without inlining functions, the compiler can decide which functions to inline. The programmer has little or no control over which functions are inlined and which are not. Given this degree of control, the programmer can choose to inline for a specific application.
Function inlining problem
Apart from the related issue of inline expansion in general, language features as an inline function may not be considered valuable for the reasons they appear, for a number of reasons:
Often, a compiler is in a better position than a human to decide whether a particular function should be inlined. Sometimes, the compiler may not be able to inline as many functions as the programmer indicates.
An important point to note is that the code (inline function) gets exposed to its clients (calling functions).
As functions evolve, they may become suitable for inlining where they were not before, or no longer suitable for inlining where they were before. While inlining or de-inlining a function is easier than converting from macros, it still requires additional maintenance and generally yields relatively little benefit.
The proliferation of native C-style compilation systems can increase compilation time for inline functions, because an intermediate representation of their bodies is copied to each call site where they are inlined. The possible increase in code size is mirrored by the possible increase in compilation time.
The C99 inline specification requires only one additional external definition of a function in another compilation unit, and the corresponding inline definition can occur multiple times in different compilation units if the function is used in place. This can easily lead to errors in the linker because such definitions are not provided by the programmer. For this reason, inline is often used together with static in C99 to also give the function internal linkage.
In C++, it is necessary to define an inline function in every module (compilation unit) to use a normal function, and it must be defined in only one module. Otherwise, it would be impossible to compile one module independently of all other modules.
For issues with functionality per se, rather than the language, see Problems with expanding with inline.
Macro comparison
The function of inline function is similar to that of preprocessor macro. I believe everyone has used preprocessor macro. We often define some macros, such as
#define TABLE_COMP(x) ((x)>0?(x):0)
A macro is defined.
Why use macros? Because the function call must transfer the program execution order to the function
The address stored in the memory will return to the execution after the program content of the function is executed.
This transfer operation requires saving the scene and memorizing the execution location before transferring execution.
After the function is called, it needs to restore the original address and continue to execute according to the original saved address.
The macro only takes a certain amount of time and space to process.
Code expansion does not require additional space and time overhead, so calling a macro is faster than calling a
Functions are more efficient.
But macros also have many unsatisfactory aspects.
1. Macros cannot access private members of objects.
2. The definition of macros can easily be ambiguous.
Let’s take an example:
#define TABLE_MULTI(x) (x*x)
We call it with a number, TABLE_MULTI(10), which seems to be correct.
The result returns 100, which is correct. However, if we call it with TABLE_MULTI(10+10),
The expected result is 400, but the result of the macro call is (10+10*10+10), which is 120.
This is obviously not the result we want. One way to avoid these errors is to put parentheses around the macro parameters.
#define TABLE_MULTI(x) ((x)*(x))
This ensures that there will be no errors, but even with this definition, the macro may still
Errors occur when, for example, they call it with TABLE_MULTI(a++) when they expect to get (a+1)*(a+1).
The result is, but what is the actual result? We can look at the macro expansion result: (a++)*(a++), if the value of a is
4, the result we get is 4*4 = 16, a = 6. And the result we expect is 5*5=25, which is a problem again.
In fact, there are also these problems in some C library functions. For example: Toupper (* pChar ++) will
pChar performs two ++ operations because Toupper is actually a macro as well.
We can see that macros have some unavoidable problems. How can we solve them?
The following is to use the inline function I will introduce to solve these problems. We can use the inline function
To replace the macro definition. And in fact we can completely replace the preprocessor macro with an inline function.
The difference between inline functions and macros is that macros are replaced by the preprocessor, while inline functions are replaced by
This is achieved through compiler control. Inline functions are real functions that are only used when needed.
When inline functions are expanded like macros, the stack push of function parameters is cancelled, reducing the number of call openings.
You can call an inline function just like a function without having to worry about the overhead of processing macros.
some problems.
We can use Inline to define inline functions, however, any function defined in the class declaration part
All functions are automatically considered inline functions.
Next we introduce the usage of inline functions.
Inline functions must be declared together with the function body to be effective.
Inline Tablefunction(int I) has no effect. The compiler just treats the function as a normal function.
To declare a function, we must define the function body.
Inline tablefunction(int I) {return I*I};
This is how we define an inline function. We can call it like a normal function.
However, the execution speed is faster than that of general functions.
We can also define functions defined outside a class as inline functions, for example:
Class TableClass{
Private:
Int I,j;
Public:
Int add() { return I+j;};
Inline int dec() { return Ij;}
Int GetNum();
}
inline int tableclass::GetNum(){
return I;
}
The three functions declared above are all inline functions. In C++, the function body is defined inside the class.
Functions are considered inline functions by default, regardless of whether you have the inline keyword.
Inline functions are most widely used in C++ classes to define access functions.
In a class, data members are usually defined as private or protected, so that the outside world cannot directly read and write them.
The data of our class members.
The reading and writing of private or protected members must be done using member interface functions.
If these read and write member functions are defined as inline functions, better efficiency will be achieved.
Class sample{
Private:
Int nTest;
Public:
Int readtest(){ return nTest;}
Void settest(int I) {nTest=I;}
}
Of course, inline functions also have certain limitations. That is, the execution code in the function cannot be too much, such as
If the body of the inline function is too large, the general compiler will abandon the inline method and use the normal method.
Call the function. In this way, the execution efficiency of the inline function is the same as that of the ordinary function.
Precautions
Things to note when using inline functions
Inline functions have the characteristics of general functions. The only difference between them and general functions is the processing of function calls. When a general function is called, the program execution right is transferred to the called function and then returned to the calling function; when an inline function is called, the calling expression is replaced by the inline function body. When using inline functions, the following points should be noted: 1. Loop statements and switch statements are not allowed in inline functions. If an inline function has these statements, the compiler will treat the function as a normal function and generate function call code. Recursive functions (functions that call themselves) cannot be used as inline functions. Inline functions are only suitable for small functions with only 1 to 5 lines. For a large function with many statements, the overhead of function calls and returns is relatively insignificant, so there is no need to implement it with inline functions. 2. The definition of an inline function must appear before the inline function is called for the first time. 3. In the class structure mentioned in this column, all functions defined inside the class description are inline functions.
Previous article:IAR STM32 absolute address positioning of functions and variables
Next article:STM32 keil mdk startup code analysis
Recommended ReadingLatest update time:2024-11-16 19:56
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- How does FPGA adjust the volume of the buzzer?
- [Repair] Repaired a data cable
- How long will the battle between community owners and communication base stations last?
- Please tell me the winding method and other parameters of the EE8 transformer that can increase 0.7V to 7V
- Conversion between CC2640R2F projects
- Pengfeng Technology RVBoards-Nezha (RISC-V SBC) Allwinner Development Board Introduction Part 3
- Cadence Certus Closure Solution is a new generation chip-level convergence solution. Welcome to learn more!
- What is the progress of domestic NPU chips?
- How is JTAG used for chip testing?
- Talk about downloading the DSP28335 register manual