C++ inline member function in .cpp file
I know that inline member functions by definition should go into the header. But what if it's not possible to put the implementation of the function into the header? Let's take this situation:
File A.h
#pragma once
#include "B.h"
class A{
B b;
};
File B.h
#pragma once
class A; //forward declaration
class B{
inline A getA();
};
Due to the circular include I have to put the implementation of getA
into
B.cpp
#include "B.h"
#include "A.h"
inline A B::getA(){
return A();
}
Will the compiler inline getA
? If so, which inline keyword is the significant one (the one in the header or the one in the .cpp file)? Is there another way to put the definition of an inline member function into its .cpp file?
Quoting from C++ FAQ:
Note: It's imperative that the function's definition (the part between the {...}) be placed in a header file, unless the function is used only in a single .cpp file. In particular, if you put the inline function's definition into a .cpp file and you call it from some other .cpp file, you'll get an "unresolved external" error from the linker.
The compiler need to see the definition of the inline function whenever it finds any use of that inline function. That is typically possible if the inline function is placed in a header file.
Will the compiler inline getA?
No, except when the the use of getA()
is in B.cpp itself.
If so, which inline keyword is the significant one (the one in the header or the one in the cpp)?
Best practice: only in the definition outside the class body.
Is there another way to put the definition of an inline member function into it's cpp file?
No, at least I don't know.
It can't, outside the scope of B.cpp. The compiler operates on a per-compile-unit base, i.e. it compiles each .cpp file individually, so if it compiles C.cpp, it won't have the code for getA() available and will need to perform a function call and have the linker fix it up (or, if it really took you by the word and tried to inline, it will have end up with a linker error. inline
has similar qualities as static
).
The only exception is LTCG, i.e. link-time code generation, which is available on newer compilers.
One approach in this case is to have another header file (sometimes named *.inl files) that contain the inlined code.
EDIT: As for which inline is relevant - it's the one in the class definition, i.e. in the header file. Keep in mind that many compilers have their own mind on what can and should be inlined. gcc for example can disable inlining completely (-O0), or it can inline anything that it deems worth inlining (like -O3).
I would go about this from the opposite direction.
Don't add inline declarations to your function (unless you need too).
The only time you need to add the inline declaration to a function/method is if you define the function in a header file but outside the class declaration.
X.h
class X
{
public:
int getX() { return 4;} // No inline because it is part of the class.
// The compiler knows that needs an inline tag
int getY();
int getZ();
};
inline
int X::getY() { return 5;} // This needs to be explicitly declared inline.
// Otherwise the linker will complain about
// multiple definitions in compilation units.
X.cpp
// Never declare anything inline in the cpp file.
int X::getZ() { return 6; }
To you more specific case.
Remove all the inline specifications. They are not doing what you think they are doing.
These days, most compilers can perform inlining at link time, as well as compile time. If your function is likely to benefit from inlining, then the Link Time optimizer is likely to do just that.
By the time the linker gets to it, not much about the inline status of compiler output is available, except that the compiler will flag certain objects as being collectible, for instance because an inline function or class template instance appears in multiple compilation units, or it should raise an error when multiple symbols share a name, such as the main function being defined twice. None of this has influence on the actual code it will generate.