Inline Functions
In C++, an inline function is a function for which the compiler attempts to generate inline code.
This means that instead of making a regular function call, the compiler replaces the function call with the actual code of the function.
It is used primarily to reduce the function call overhead and improve performance, especially for small, frequently called functions.
The function call overhead is basically the steps that are taken when a function is called. Here is a breakdown:
- The arguments of the function are evaluated and placed either in registers or on the stack.
- The current execution point (Instruction Pointer - IP) is saved so the program knows where to return to after the function execution is complete.
- The control is transferred to the called function, which involves a jump in the instruction sequence.
- A new stack frame is created for the called function. The stack frame contains space for the local variable, the return address, and saved register values that need to be restored after the function returns.
- The function's code is executed with its local variables and arguments.
- After the function finishes execution, its stack frame is torn down, local variables are cleaned up, and saved registers are restored.
- The return value of the function (if any) is placed in the appropriate location (register or stack).
- Control is transferred to the point in the program where the function was called, using the saved return address.
Inline function helps reduce this function overhead by embedding the code function directly into the caller's code.
This immediately results in NO arguments passing, control transfer, or stack frame setup/teardown.
inline return-type function-name(parameters) {
// Function Code
}
It's important to note that: inlining is only a request to the compiler, not a command. The compiler can ignore the request for inlining.
The compiler may ignore inlining according to the following cases:
- If the function is recursive.
- If the function contains loops (for, while, or do-while).
- If the function contains static variables.
- If the function contains loop or go-to statements.
- If the function does NOT have a return statement. (Of course, this doesn't apply for void functions since they don't need a return statement).
There are some setbacks that may result from inlining a function. Here's some:
- Using too much inlining can result in increasing the size of the binary executable file because of the duplication of the same code.
- Using too much inlining can reduce the instruction cache hit rate, resulting in reducing the speed of the instruction fetch from that of the cache memory to that of primary memory.
- Inlining may increase compile time overhead if the code of the function changes since all the calling locations have to be recompiled again or, otherwise, will continue with the old functionality.
- Inlining may cause memory thrashing because it increases the size of the binary executable file. Thrashing causes the performance of the computer to degrade.
*All the functions inside the class are implicitly inline. Therefore, all the restrictions of inline functions are also applied here.
In case you want to explicitly declare an inline function inside the class, declare the function inside the class and define it outside the class using the inline keyword.
class Sample {
public:
inline int squar(int N) {
return N * N;
}
};
As always, it's essential to consider whether inlining is appropriate for the specific function and the impact it may have on your code's performance and size.