A key feature of C++ is the inline function. Therefore, let’s first understand the usage and intended applications of inline functions. When a function is declared as an inline function, the compiler will replace the location of the function call with the definition of the inline function at compile time.
Any changes to the inline function require recompilation of the inline function, as the compiler needs to replace all code with the new code; otherwise, the old functionality will be executed.
In short, when the program executes a function call instruction, the CPU copies the function’s parameters onto the stack, caches the memory address of the next instruction, and then transfers control to the target function. The CPU executes the function’s code, stores the return value in the specified memory address or register, and returns control to the calling function. If the execution time of the function is shorter than the switching time from the calling function to the called function, this can become an overhead. Compared to the time required to run large or complex functions, the overhead of function calls is usually negligible. However, the call time of small frequently used functions often far exceeds the time required to run the function code. Because their execution time is less than the switching time, small functions encounter this overhead. To minimize the overhead of function calls, C++ provides inline functions. When an inline function is called, its complete code body is expanded at the location of the inline function call. The C++ compiler performs this replacement at compile time. If the inline function is small, it can improve efficiency. For the compiler, inline is merely a request; it is not a command. The compiler can refuse the inline request.
The compiler may not implement inline under the following circumstances:
-
If the function contains loops (for, while, do-while).
-
If the function has static variables.
-
If the function is recursive.
-
If there is no return statement in the function body and the return type of the function is not void.
-
If the function uses goto or switch statements.
👇Click to claim👇
👉C Language Knowledge Resource Collection
Syntax of Inline Functions:
inline return_type function_name(parameters){ // function code}
Let’s understand the difference between a normal function and an inline function.
In the main() method, when the fun1() function is called, control is transferred to the definition of the called function. The address where the function is called and the address of the function definition are different. This control transfer takes a lot of time, increasing the overhead.
When an inline function is encountered, the definition of the function is copied to the call location. In this case, there is no control transfer, which saves a lot of time and reduces overhead.
Let’s understand this with an example.
#include <iostream>
using namespace std;
inline int add(int a, int b){ return(a+b);}
int main(){ cout << "Addition of 'a' and 'b' is:" << add(2,3); return 0;}</iostream>
After compilation, the code will look like this:
#include <iostream>
using namespace std;
inline int add(int a, int b){ return(a+b);}
int main(){ cout << "Addition of 'a' and 'b' is:" << return(2+3); return 0;}</iostream>
Why do we need inline functions in C++?
The main purpose of inline functions in C++ is to save memory space. Whenever a function is called, executing tasks (such as going to the calling function) takes a long time. If the function is very small, a lot of execution time can be spent on such overhead, sometimes the time taken to go to the calling function is greater than the time required to execute that function.
The solution to this problem is to use macros defined as macro definitions. Preprocessor macros are widely used in C, but the main drawback of macros is that they are not normal functions, meaning they do not undergo error checking during compilation.
C++ provides a solution. In the case of function calls, the time taken to call such small functions is long, so to solve this problem, a new concept called inline functions was introduced. When a function is encountered, it expands with its definition, thus saving time.
We cannot inline a function under the following conditions:
-
If the function is recursive.
-
If the function contains loops, such as for, while, do-while loops.
-
If the function contains static variables.
-
If the function contains switch or goto statements.
When should inline functions be used?
Inline functions can be used in the following situations:
-
Inline functions can be used when performance is needed.
-
Inline functions can replace macro definitions.
-
Inline functions can be used outside of classes to hide the internal implementation of the function.
Advantages of Inline Functions
-
In inline functions, there is no need to call the function, so there is no overhead.
-
It also saves the overhead of returning from the function.
-
It does not require any stack to push or pop variables since it does not perform any function calls.
-
For embedded systems, inline functions generate less code than normal functions, making them very beneficial for embedded systems.
Disadvantages of Inline Functions
-
Variables created within inline functions consume additional registers. If the number of variables increases, the use of registers will also increase, which may increase the overhead of resource utilization of register variables. That is, when replacing function calls with inline function bodies, the number of variables will also increase, leading to an increase in the number of registers. This increases the overhead of resource utilization.
-
If many inline functions are used, the size of the binary executable file may also increase.
-
Using too many inline functions may reduce the hit rate of the instruction cache, reducing the speed of instruction fetching from cache memory to main memory. It also increases the overhead at compile time because whenever changes are made inside an inline function, the code needs to be recompiled to reflect those changes; otherwise, it will execute the old functionality.
-
Sometimes, inline functions are not practical for many embedded systems because, in some cases, the size of the embedded system is considered more important than speed.
-
Due to the increase in the size of the binary executable file, it may also lead to thrashing. If thrashing occurs in memory, it can lead to a decrease in computer performance.
What is the problem with macros?
Readers familiar with C know that it uses macros. In macro code, all direct macro calls are replaced by the preprocessor. It is recommended to always use inline functions instead of macros. Dr. Bjarne Stroustrup, the inventor of C++, stated that there is little need to use macros in C++, and macros are prone to errors. Using macros in C++ is not without problems. Private class members are inaccessible to macros. Although macros resemble function calls, they are not true function calls.
For example:
#include <iostream>
using namespace std;
class S{ int m; public: #define MAC(S::m) // error};</iostream>
The C++ compiler will verify that the necessary conversions are completed and validate the parameter types of inline functions. Preprocessor macros cannot perform these operations. Additionally, the preprocessor manages macros, while the C++ compiler manages inline functions. Remember, while all functions specified in a class will be implicitly inlined, and the C++ compiler will perform inline calls to these functions, if the function is a virtual function, it cannot be inlined. The reason is that virtual function calls are resolved at runtime rather than at compile time. If the compiler does not know which function will be called, how can it perform inline processing at compile time, while virtual functions mean waiting for runtime? It is also important to remember that inlining a function is only beneficial when the time required to call the function is greater than the time required to execute the function body. For example:
For example:
inline void show(){ cout << "value of S = " << S << endl;}
Executing the above function takes some time. The basic rule is that functions performing input-output (I/O) operations should not be defined as inline functions because they take a long time. Since the time required for I/O statements is much longer than that for function calls, technically, inlining the show() function has limited utility.
If a function is not expanded as an inline function, a warning may be displayed depending on the compiler used. Inline functions cannot be used in programming languages like Java or C#.
However, since final methods cannot be overridden by subclasses, and calls to final methods are handled at compile time, the Java compiler can inline when calling small final procedures. By inlining short function calls, the JIT compiler can further optimize C# code (for example, replacing small function bodies when called in loops).
Popular Recommendations
-
“616” work system? Netizens: Even a donkey would go on a hunger strike upon seeing this slogan.
-
CLion Tutorial – Multi-Cursor and Range Selection in CLion
-
C Language Algorithm – “Convert Sorted Array to Binary Search Tree” Algorithm Problem