Writing function definition in header files in C++
I have a class which has many small functions. By small functions, I mean functions that doesn't do any processing but just return a literal value. Something like:
string Foo::method() const{
return "A";
}
I have created a header file "Foo.h" and source file "Foo.cpp". But since the function is very small, I am thinking about putting it in the header file itself. I have the following questions:
- Is there any performance or other issues if I put these function definition in header file? I will have many functions like this.
- My understanding is when the compilation is done, compiler will expand the header file and place it where it is included. Is that correct?
Solution 1:
If the function is small (the chance you would change it often is low), and if the function can be put into the header without including myriads of other headers (because your function depends on them), it is perfectly valid to do so. If you declare them extern inline, then the compiler is required to give it the same address for every compilation unit:
headera.h:
inline string method() {
return something;
}
Member functions are implicit inline provided they are defined inside their class. The same stuff is true for them true: If they can be put into the header without hassle, you can indeed do so.
Because the code of the function is put into the header and visible, the compiler is able to inline calls to them, that is, putting code of the function directly at the call site (not so much because you put inline before it, but more because the compiler decides that way, though. Putting inline only is a hint to the compiler regarding that). That can result in a performance improvement, because the compiler now sees where arguments match variables local to the function, and where argument doesn't alias each other - and last but not least, function frame allocation isn't needed anymore.
My understanding is when the compilation is done, compiler will expand the header file and place it where it is included. Is that correct?
Yes, that is correct. The function will be defined in every place where you include its header. The compiler will care about putting only one instance of it into the resulting program, by eliminating the others.
Solution 2:
Depending on your compiler and it's settings it may do any of the following:
- It may ignore the inline keyword (it is just a hint to the compiler, not a command) and generate stand-alone functions. It may do this if your functions exceed a compiler-dependent complexity threshold. e.g. too many nested loops.
- It may decide than your stand-alone function is a good candidate for inline expansion.
In many cases, the compiler is in a much better position to determine if a function should be inlined than you are, so there is no point in second-guessing it. I like to use implicit inlining when a class has many small functions only because it's convenient to have the implementation right there in the class. This doesn't work so well for larger functions.
The other thing to keep in mind is that if you are exporting a class in a DLL/shared library (not a good idea IMHO, but people do it anyway) you need to be really careful with inline functions. If the compiler that built the DLL decides a function should be inlined you have a couple of potential problems:
- The compiler building the program using the DLL might decide to not inline the function so it will generate a symbol reference to a function that doesn't exist and the DLL will not load.
- If you update the DLL and change the inlined function, the client program will still be using the old version of that function since the function got inlined into the client code.
Solution 3:
There will be an increase in performance because implementation in header files are implicitly inlined. As you mentioned your functions are small, inline operation will be so beneficial for you IMHO.
What you say about compiler is also true.There is no difference for compiler—other than inlining—between code in header file or .cpp
file.
Solution 4:
If your functions are that simple, make them inline, and you'll have to stick them in the header file anyway. Other than that, any conventions are just that - conventions.
Yes, the compiler does expand the header file where it encounters the #include statements.