When should I write the keyword inline
for a function/method in C++?
After seeing some answers, some related questions:
When should I <
I'd like to contribute to all of the great answers in this thread with a convincing example to disperse any remaining misunderstanding.
Given two source files, such as:
inline111.cpp:
#include <iostream>
void bar();
inline int fun() {
return 111;
}
int main() {
std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
bar();
}
inline222.cpp:
#include <iostream>
inline int fun() {
return 222;
}
void bar() {
std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
}
Case A:
Compile:
g++ -std=c++11 inline111.cpp inline222.cpp
Output:
inline111: fun() = 111, &fun = 0x4029a0
inline222: fun() = 111, &fun = 0x4029a0
Discussion:
Even thou you ought to have identical definitions of your inline functions, C++ compiler does not flag it if that is not the case (actually, due to separate compilation it has no ways to check it). It is your own duty to ensure this!
Linker does not complain about One Definition Rule, as fun()
is declared as inline
. However, because inline111.cpp is the first translation unit (which actually calls fun()
) processed by compiler, the compiler instantiates fun()
upon its first call-encounter in inline111.cpp. If compiler decides not to expand fun()
upon its call from anywhere else in your program (e.g. from inline222.cpp), the call to fun()
will always be linked to its instance produced from inline111.cpp (the call to fun()
inside inline222.cpp may also produce an instance in that translation unit, but it will remain unlinked). Indeed, that is evident from the identical &fun = 0x4029a0
print-outs.
Finally, despite the inline
suggestion to the compiler to actually expand the one-liner fun()
, it ignores your suggestion completely, which is clear because fun() = 111
in both of the lines.
Case B:
Compile (notice reverse order):
g++ -std=c++11 inline222.cpp inline111.cpp
Output:
inline111: fun() = 222, &fun = 0x402980
inline222: fun() = 222, &fun = 0x402980
Discussion:
This case asserts what have been discussed in Case A.
Notice an important point, that if you comment out the actual call to fun()
in inline222.cpp (e.g. comment out cout
-statement in inline222.cpp completely) then, despite the compilation order of your translation units, fun()
will be instantiated upon it's first call encounter in inline111.cpp, resulting in print-out for Case B as inline111: fun() = 111, &fun = 0x402980
.
Case C:
Compile (notice -O2):
g++ -std=c++11 -O2 inline222.cpp inline111.cpp
or
g++ -std=c++11 -O2 inline111.cpp inline222.cpp
Output:
inline111: fun() = 111, &fun = 0x402900
inline222: fun() = 222, &fun = 0x402900
Discussion:
-O2
optimization encourages compiler to actually expand the functions that can be inlined (Notice also that -fno-inline
is default without optimization options). As is evident from the outprint here, the fun()
has actually been inline expanded (according to its definition in that particular translation unit), resulting in two different fun()
print-outs. Despite this, there is still only one globally linked instance of fun()
(as required by the standard), as is evident from identical &fun
print-out.When one should inline :
1.When one want to avoid overhead of things happening when function is called like parameter passing , control transfer, control return etc.
2.The function should be small,frequently called and making inline is really advantageous since as per 80-20 rule,try to make those function inline which has major impact on program performance.
As we know that inline is just a request to compiler similar to register and it will cost you at Object code size.
C++ inline function is powerful concept that is commonly used with classes. If a function is inline, the compiler places a copy of the code of that function at each point where the function is called at compile time.
Any change to an inline function could require all clients of the function to be recompiled because compiler would need to replace all the code once again otherwise it will continue with old functionality.
To inline a function, place the keyword inline before the function name and define the function before any calls are made to the function. The compiler can ignore the inline qualifier in case defined function is more than a line.
A function definition in a class definition is an inline function definition, even without the use of the inline specifier.
Following is an example, which makes use of inline function to return max of two numbers
#include <iostream>
using namespace std;
inline int Max(int x, int y) { return (x > y)? x : y; }
// Main function for the program
int main() {
cout << "Max (100,1010): " << Max(100,1010) << endl;
return 0;
}
for more information see here.