Inline Functions
The
inline keyword is one of C++'s oldest optimization hints. Its original purpose — suggesting that a function's body be substituted directly at each call site — matters much less today, but the keyword has taken on an important second role in modern C++.What inline Originally Meant
Normally, calling a function involves some overhead: pushing arguments, jumping to the function's code, and returning. Marking a small function
inline suggests to the compiler that it should instead paste the function's body directly into the caller, eliminating that call overhead entirely.CPP
inline int square(int x) {
return x * x;
}
int main() {
int result = square(5);
// The compiler may effectively rewrite this as:
// int result = 5 * 5;
return 0;
}inline Is a Hint, Not a Guarantee
The
inline keyword does not force the compiler to do anything. It is only a suggestion — the compiler is completely free to ignore it (for a function that's too large or too complex to sensibly inline) or to inline a function that isn't marked inline at all, if its own heuristics decide it's worthwhile.Note
Modern compilers perform aggressive automatic inlining based on their own cost/benefit analysis, especially with optimizations enabled (-O2, -O3). As a result, manually adding
inline to hint at performance rarely changes generated code for a modern optimizing compiler — it will typically inline small, hot functions whether you ask it to or not, and decline to inline large ones even if you do ask.Why inline Still Matters Today
Despite the above,
inline is still required in one important, very common situation: defining a (non-template, non-member) function directly inside a header file that gets #included by multiple .cpp files.Without
inline, each .cpp file that includes the header gets its own copy of the function definition. When the linker combines all the compiled object files into one program, it finds the same function defined multiple times and reports a multiple-definition linker error.CPP
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
// Without 'inline', including this header in two .cpp files
// causes a linker error: "multiple definition of square(int)".
inline int square(int x) {
return x * x;
}
#endifWarning
If you define a regular (non-template) function inside a header without
inline, and that header is included by more than one .cpp file in the same program, you will get a linker error about a duplicate/multiple definition. Marking it inline tells the linker it's allowed to see multiple identical definitions and just keep one.Alternatives
The usual alternative is to keep only the declaration in the header and put the definition in exactly one .cpp file, so it's only defined once across the whole program. Class member functions defined directly inside a class body are implicitly
inline already, which is why small getters/setters written inline in a class definition don't cause this problem.CPP
class Circle {
public:
// Defined inside the class body - implicitly inline, safe to
// include this header everywhere without linker errors.
double area() const {
return 3.14159 * radius * radius;
}
private:
double radius = 1.0;
};Key Points
inline originally hinted that a function body should be substituted at each call site.
It is only a hint - the compiler can ignore it, or inline unmarked functions on its own.
Modern optimizing compilers already inline small, hot functions automatically, reducing the hint's usefulness.
inline is still required for non-template functions defined in a header included by multiple .cpp files, to avoid multiple-definition linker errors.
Member functions defined directly inside a class body are implicitly inline.