The inline keyword is one of the most misunderstood features in C++. It once asked the compiler to inline a function for speed; today it does something almost entirely different.
tldr:
inlinewas originally a performance hint to the compiler.- Modern compilers ignore that hint; they decide for themselves.
- Today,
inlineserves a different role
The cost of a function call
There is overhead when calling a function. In the following program, the CPU:
- Save the address of the current instruction.
- Evaluate and pass the arguments.
- Jump to the function’s code.
- Return to the saved address afterwards.
For small function calls, this overhead can actually be larger than the time required to execute the code. This performance penalty is incurred with every function call.
#include <iostream>
int min(int x, int y)
{
return (x < y) ? x : y;
}
int main()
{
std::cout << min(5, 6) << '\\n';
std::cout << min(3, 2) << '\\n';
}
Enter inline expansion
This is a trick used by the compiler to avoid the overhead cost associated with calling functions.
Inline expansion is a process where a function call is replaced by the code from the called function’s definition. If the example above was made inline, the compiler would treat it like this:
#include <iostream>
int main()
{
std::cout << ((5 < 6) ? 5 : 6) << '\\n';
std::cout << ((3 < 2) ? 3 : 2) << '\\n';
}
The expression is evaluated in place.
The historical use of inline
Back when compilers were slow and less capable, the programmer could add inline to a function. This signals to the compiler that this function is eligible for inline expansion.
inline int min(int x, int y)
{
return (x < y) ? x : y;
}
However, fast forward to the modern day and compilers are very good at determining when to inline a function. As a result, the compiler will likely ignore or devalue any use of inline to request inline expansion for your functions. This is obsolete.
Additionally, using inline can actually impair performance since it is a form of premature optimization.
Avoid the use of the
inlinekeyword unless you have a specific, compelling reason to do so
The modern meaning of inline
In modern C++, inline permits a function or variable to be defined in multiple translation units without violating the One Definition Rule (ODR).
The linker sees the duplicate definitions and accepts them, provided they are identical.
This is why you can safely define a function in a header file like so:
// math_utils.h
inline int min(int x, int y){
return (x < y) ? x : y;
}
If two .cpp files include this header, both translation units end up with their own definition of min. Without inline, the linker would reject the program. With inline, it accepts it.
NOTE: C++17 extended the same mechanism to variables with
inlinevariables
In Summary
Compilers have outgrown the use of inline as a tool for performance optimization. Rather get acquainted with the new role of inline. Being able to define an identifier across multiple translation units without violating ODR.