Why and why not inline
Kexin Tang

Why inline

In C++, we can add inline keyword in front of function defination (inline only works on defination, you don’t need to use inline in statement).

1
2
3
4
5
void this_is_inline_func();

inline void this_is_inline_func() {
std::cout << "this is inline func" << std::endl;
}

no inline

When we call a function, the process is

  1. find function defination and its address
  2. load from memory to stack
  3. execute
  4. pop from stack
1
2
3
4
5
6
7
void this_is_not_inline() {
...
}

this_is_not_inline(); // 1
this_is_not_inline(); // 2
this_is_not_inline(); // 3
1
2
3
4
5
0x0000 -> defination of this_is_not_inline
...
0x0100 -> call 1 // find address is 0x0000 -> push 0x0000 into stack -> execute -> pop
0x0104 -> call 2 // same
0x0108 -> call 3 // same

inline

All of these steps will cost extra time. To avoid this cost, we can use inline. After we defining a function as inline, we may have multiple calls in code. When we compile the code, the compiler will change function calls to function defination, so that when execute the code, instead of wasting time finding defination and loading from memory to stack, it just executes the function logic.

1
2
3
4
5
6
7
void this_is_inline() {
std::cout << "this is inline func" << std::endl;
}

this_is_inline(); // 1
this_is_inline(); // 2
this_is_inline(); // 3
1
2
3
4
5
0x0000 -> defination of this_is_inline
...
0x0100 -> std::cout << "this is inline func" << std::endl; // change call to defination
0x0200 -> std::cout << "this is inline func" << std::endl;
0x0300 -> std::cout << "this is inline func" << std::endl;

Why not inline

Sounds great? But the problem is, we need to copy the defination after every calls. If the defination is very complicated, we will cost losts of memory. What’s more, if the function is complicated, the execution time >> load & pop stack time, we can ignore the inline improvement.


Suggestion

Only use inline for very simple function. Actually inline is just a recommendation rather than requirement. If the function contains loop, recursion, static, etc complex logic, the function will be treated as not-inline even if you add inline keyword.

What’s more, in class, the methods defination will be treated as inline. So only define simple methods in class, for complex methods, leave statements inside class, then define them outside class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Object {
public:
Object() =default;
Object(const Object& rhs) { num = rhs.num; }
int get_num() { return num; } // define simple method inside class (auto inline)
void inline_function();
void complex_function();
private:
int num;
};

// we can still define inline outside class
inline void Object::inline_function() {
...
}

// for complex method, plz define outside class
void Object::complex_function() {
...
}

#define vs inline

#define replaces the pure text in pre-complie stage, inline replaces function call with function defination in complie stage.