Keyword
It's a common myth that the inline
specifier in C++ is
ignored by the compiler. While the standard states that it's only a hint for
the compiler at least on Visual Studio 2019 the inlining process is influenced
by the keyword.
Test case
For the test case the following class is used:
struct Dummy
{
explicit Dummy (int n);
int Get () const; // defined in cpp
int GetInline () const;
private:
int m_n;
};
inline int Dummy::GetInline() const
{
return m_n;
}
Assembly
The use of inlining by the compiler can be studied by looking at the
produced assembly in release mode. Tip to use
DebugBreak()
under debugger to stop around call location.
For normal function invocations it looks like:
00007FF71ECF166C lea rcx,[rsp+30h]
00007FF71ECF1671 call Dummy::Get (07FF71ECF1730h)
00007FF71ECF1676
00007FF71ECF167C
00007FF71ECF1680 add ecx,eax
The inlined version looks like:
00007FF71ECF1676
00007FF71ECF167C add ecx,dword ptr [rsp+38h]
For function invocation a call
instruction is issued while
the inlined version uses an add of the memory content to register
ecx
. The assembly code for the non inlined function definition is
a plain memory copy instruction so performance wise the call is just overhead.
Results
Tests take place on Visual Studio 2019 version 16.8.3 with a x64 build in release mode. The following cases are tested:
- use class inside a module
-
use class inside a module with /LTCG (i.e. 'link time code generation')
- use exported class (i.e. the class is exported from a DLL and used in another module)
The results are as follow:
Case | Get | GetInline |
---|---|---|
use inside a module | not inlined | inlined |
use inside a module with /LTCG | inlined | inlined |
use exported class | not inlined | inlined |
Conclusion
The inline
keyword is not ignored by Visual Studio 2019
and used as a hint. Recommendation to use it where applicable (e.g. one line
'getters' and performance intensive use cases).
The use of inline
in a DLL context is food for discussion but it's okay as
long as you rebuild the DLL (and its clients) when you change the source code
of the DLL. MFC and boost are standard examples.
Other aspects not discussed here are use in (exported) templates and constexpr constructors (with noexcept).
External links
- https://devblogs.microsoft.com/cppblog/inlining-decisions-in-visual-studio/
No comments:
Post a Comment