As general rules:
You should mark a function inline
if you intent to define it in a header file (included by multiple translation units, aka .cpp
files). It is not allowed to define a function which is not inline
in multiple translation units. So this is necessary.
If the function is also static
(at namespace scope), constexpr
, is a function template or is defined inside a class definition, then inline
is redundant and can/should be left out.
If the function is defined in a .cpp
file and only used in this one translation unit it may be declared inline
, but any performance implications of that are at best going to be minimal. A compiler will make its own decision on inlining anyway. inline
is either completely ignored or a minor hint in the decision making process at best.
If the function is defined in a .cpp
file and a declaration of it is included in multiple translation units via a header file, then it must not be declared inline
. The inline
specifier implies that you guarantee that a definition of the function will be available in any translation unit using it (and that all definitions will be identical).
The thing that is really performance-relevant here is not the inline
specifier as such, but making the decision of whether you want to include the function definition in all translation units (meaning a header file) or only in one translation unit (meaning a .cpp
file). Including in all translation units means that the compiler has it easier to perform inlining, not due to the inline
keyword, but the fact that the definition is visible during the compilation process for the unit. However, nowadays we also have link time optimization which applies optimizations across all translation units when enabled and for which even that visibility of the definition doesn't really matter anymore.