When should I write the keyword inline
for a function/method in C++?
After seeing some answers, some related questions:
When should I not write the keyword 'inline' for a function/method in C++?
When will the compiler not know when to make a function/method 'inline'?
Does it matter if an application is multithreaded when one writes 'inline' for a function/method?
Unless you are writing a library or have special reasons, you can forget about
inline
and use link-time optimization instead. It removes the requirement that a function definition must be in a header for it to be considered for inlining across compilation units, which is precisely whatinline
allows.(But see Is there any reason why not to use link time optimization?)
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.
1) Nowadays, pretty much never. If it's a good idea to inline a function, the compiler will do it without your help.
2) Always. See #1.
(Edited to reflect that you broke your question into two questions...)
I checked this for Visual Studio 9 (15.00.30729.01) by compiling with /FAcs and looking at the assembly code: The compiler produced calls to member functions without optimization enabled in debug mode. Even if the function is marked with __forceinline, no inline runtime code is produced.
If the function is defined in the
.cpp
file, you should not write the keyword.There is no such situation. The compiler cannot make a function inline. All it can do is to inline some or all calls to the function. It can't do so if it hasn't got the code of the function (in that case the linker needs to do it if it is able to do so).
No, that does not matter at all.
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:
inline222.cpp:
Case A:
Compile:
Output:
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 asinline
. However, because inline111.cpp is the first translation unit (which actually callsfun()
) processed by compiler, the compiler instantiatesfun()
upon its first call-encounter in inline111.cpp. If compiler decides not to expandfun()
upon its call from anywhere else in your program (e.g. from inline222.cpp), the call tofun()
will always be linked to its instance produced from inline111.cpp (the call tofun()
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-linerfun()
, it ignores your suggestion completely, which is clear becausefun() = 111
in both of the lines.Case B:
Compile (notice reverse order):
Output:
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 outcout
-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 asinline111: fun() = 111, &fun = 0x402980
.Case C:
Compile (notice -O2):
or
Output:
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, thefun()
has actually been inline expanded (according to its definition in that particular translation unit), resulting in two differentfun()
print-outs. Despite this, there is still only one globally linked instance offun()
(as required by the standard), as is evident from identical&fun
print-out.