Skip to content
C++ Better Explained
Go back
Inline Functions in C++: What the inline Keyword Really Does

Inline Functions in C++: What the inline Keyword Really Does

Almost every tutorial tells you inline makes functions faster by pasting the body at the call site. That was true in 1995. Today it’s misleading, and believing it leads people to sprinkle inline everywhere for no benefit.

Here is what inline actually does in modern C++, and the one situation where you genuinely need it.


The Original Idea: Avoiding Call Overhead

Calling a function isn’t free. The CPU pushes arguments, jumps to another address, runs the body, and jumps back. For a tiny function inside a hot loop, that bookkeeping can cost more than the work.

Inlining means the compiler replaces the call with a copy of the body:

inline int square(int x) {
    return x * x;
}

int main() {
    int result = square(5);   // compiler may emit: int result = 5 * 5;
}

No jump, no return, and the compiler can now fold 5 * 5 into a constant at compile time. That’s a real optimisation — it’s just not one you control with the keyword.


The Keyword Is a Request, Not a Command

This is the part that surprises people: the compiler is free to ignore inline completely.

Compilers have far better information than you do — they know the function’s size, how often it’s called, and whether inlining would blow up the instruction cache. So in practice:

If you compile the square example with g++ -O2, it gets inlined whether or not you write the keyword. Remove the keyword and the generated assembly is identical.

If you're looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you're a complete beginner or looking to solidify your understanding. Just $19.

What inline Is Actually For Today

The real, non-optional job of inline is satisfying the One Definition Rule: a program may contain only one definition of any given function.

Say you put a helper in a header:

// mathutils.h
#pragma once

int square(int x) {      // definition in a header — trouble ahead
    return x * x;
}

Now two source files include it:

// main.cpp
#include "mathutils.h"
int main() { return square(4); }
// helper.cpp
#include "mathutils.h"
int helper() { return square(9); }

Each .cpp compiles fine on its own, but the linker then sees square defined twice and stops:

multiple definition of `square(int)'

The include guard doesn’t help — it only prevents double inclusion within one translation unit, not across two separate ones.

Add one keyword and the error disappears:

// mathutils.h
#pragma once

inline int square(int x) {
    return x * x;
}

inline tells the linker “you will see this definition more than once, that’s intentional, keep one and discard the rest.” That is the reason to type it.


Member Functions Defined Inside a Class Are Already Inline

You don’t need the keyword here:

class Circle {
    double radius;
public:
    Circle(double r) : radius(r) {}

    double area() const {                 // implicitly inline
        return 3.14159 * radius * radius;
    }
};

Any function defined inside the class body is implicitly inline, which is why headers full of small class methods link without complaint. You only need the explicit keyword when you define a member function outside the class, in a header:

// circle.h
class Circle {
    double radius;
public:
    double area() const;
};

inline double Circle::area() const {      // inline needed here
    return 3.14159 * radius * radius;
}

inline vs #define Macros

Before inline, people used macros to avoid call overhead. Macros are text substitution and they bite:

#define SQUARE(x) ((x) * (x))

int i = 5;
int bad = SQUARE(i++);     // expands to ((i++) * (i++)) — undefined behaviour

i++ runs twice. An inline function evaluates its argument exactly once:

inline int square(int x) { return x * x; }

int i = 5;
int good = square(i++);    // fine — i incremented once, 25 computed

Inline functions also respect types, scope, and namespaces, and debuggers can step into them. Prefer them to function-like macros in every case.


Practical Guidelines

The short version: think of inline as a linkage keyword that happens to have “inline” in the name.



Take Your C++ Further

If you’re looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you’re a complete beginner or looking to solidify your understanding. Just $19.

👉 Get the C++ Better Explained Ebook — $19

📋

Free Download: The 10 Mistakes Every C++ Beginner Makes

A free 1-page checklist that shows the exact traps that slow down every C++ beginner — so you can avoid them from day one.

🔒 No spam. Unsubscribe anytime.


Share this post on:

Written by

Sahil Bora

Software Engineer. Author and creator of C++ Better Explained.


Previous Post
The Diamond Problem in C++: Multiple Inheritance and virtual Bases
Next Post
Linear Search in C++: How It Works, With Code and Complexity

Keep Learning