When to write inline in C++: analyzing a legendary question from Stack Overflow
\n\nEvery C++ developer has asked themselves at least once: "Isn't it time to write inline before a function?". On Stack Overflow, this question has garnered thousands of views and hundreds of comments. And it's no wonder: the topic of inline functions is overgrown with myths, outdated advice, and contradictory recommendations.
In this article, we will figure out once and for all: when to use inline, when it is pointless, and when it is harmful. You will learn the real mechanics of how inline works in modern C++ (C++11 and newer), see code examples, and get clear action items for your projects.
What does inline actually do? Busting the myths
\n\nMany people think that inline is a command to the compiler to "insert the function code directly at the call site." This is an outdated and dangerous misconception. In reality:
- \n
- The modern compiler decides for itself whether to inline a function. Your
inlineis just a recommendation. \n - The main purpose of
inlinein C++ is to allow multiple definitions of the same function in different translation units (to avoid a linker error). \n - Without
inline, you cannot define a function in a header file (unless it is a template or a class method defined inside the class). \n
Let's look at a simple example. Suppose you have a header file utils.h:
// utils.h\n#ifndef UTILS_H\n#define UTILS_H\n\nint square(int x) {\n return x * x;\n}\n\n#endif\n\nIf you include this header file in two different .cpp files, the linker will give a "multiple definition" error. To fix this, you need to add inline:
// utils.h\n#ifndef UTILS_H\n#define UTILS_H\n\ninline int square(int x) {\n return x * x;\n}\n\n#endif\n\nThat's all the magic. The inline keyword primarily solves the linking problem, not speed optimization.
\n\nWhen does inline actually help the compiler?
\n\nAlthough inline is not a command but a request, the compiler may heed it. Especially if the function:
- \n
- Is small (1-3 lines of code). \n
- Is called frequently (inside a hot loop). \n
- Does not contain complex constructs (loops, recursion, virtual calls). \n
In such cases, function inlining can speed up code due to:
\n- \n
- Eliminating the overhead of a function call (saving/restoring registers). \n
- Better optimization (the compiler sees all the code at once). \n
- Reducing cache misses (the code becomes more compact at the call site). \n
But there is also a downside: excessive inlining bloats the binary, increases compilation time, and can degrade performance due to instruction cache misses.
\n\nExample: when inline is justified
\n\n// math_helpers.h\ninline int max(int a, int b) {\n return (a > b) ? a : b;\n}\n\n// main.cpp\n#include "math_helpers.h"\n\nint main() {\n int result = 0;\n for (int i = 0; i < 1000000; ++i) {\n result = max(result, i); // the compiler will most likely inline max\n }\n return result;\n}\n\nHere, max is an ideal candidate for inline: small, one line, called a million times.
Comparison of approaches: inline vs static vs constexpr
\n\nBeginners often confuse inline with other ways of placing functions in header files. Let's compare th