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?
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.
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.
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.
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.
It depends on the coding standards that apply in your case but:
Small functions without loops and anything else should be inlined for better performance (but slightly larger code - important for some constrained or embedded applications).
If you have the body of the function in the header you will have it by default inline(d) (which is a good thing when it comes to speed).
Before the object file is created by the compiler the preprocessor is called (-E option for gcc) and the result is sent to the compiler which creates the object out of code.
So the shorter answer is:
-- Declaring functions in header is good for speed (but not for space) --
C++ won’t complain if you do, but generally speaking, you shouldn’t.
when you #include a file, the entire content of the included file is inserted at the point of inclusion. This means that any definitions you put in your header get copied into every file that includes that header.
For small projects, this isn’t likely to be much of an issue. But for larger projects, this can make things take much longer to compile (as the same code gets recompiled each time it is encountered) and could significantly bloat the size of your executable. If you make a change to a definition in a code file, only that .cpp file needs to be recompiled. If you make a change to a definition in a header file, every code file that includes the header needs to be recompiled. One small change can cause you to have to recompile your entire project!
Sometimes exceptions are made for trivial functions that are unlikely to change (e.g. where the function definition is one line).
Source: http://archive.li/ACYlo (previous version of Chapter 1.9 on learncpp.com)
Related
Background: The C++ inline keyword does not determine if a function should be inlined.
Instead, inline permits you to provide multiple definitions of a single function or variable, so long as each definition occurs in a different translation unit.
Basically, this allows definitions of global variables and functions in header files.
Are there some examples of why I might want to write a definition in a header file?
I've heard that there might be templating examples where it's impossible to write the definition in a separate cpp file.
I've heard other claims about performance. But is that really true? Since, to my knowledge, the use of the inline keyword doesn't guarantee that the function call is inlined (and vice versa).
I have a sense that this feature is probably primarily used by library writers trying to write wacky and highly optimized implementations. But are there some examples?
It's actually simple: you need inline when you want to write a definition (of a function or variable (since c++17)) in a header. Otherwise you would violate odr as soon as your header is included in more than 1 tu. That's it. That's all there is to it.
Of note is that some entities are implicitly declared inline like:
methods defined inside the body of the class
template functions and variables
constexpr functions and variables
Now the question becomes why and when would someone want to write definitions in the header instead of separating declarations in headers and definitions in source code files. There are advantages and disadvantages to this approach. Here are some to consider:
optimization
Having the definition in a source file means that the code of the function is baked into the tu binary. It cannot be inlined at the calling site outside of the tu that defines it. Having it in a header means that the compiler can inline it everywhere it sees fit. Or it can generate different code for the function depending on the context where it is called. The same can be achieved with lto within an executable or library, but for libraries the only option for enabling this optimization is having the definitions in the header.
library distribution
Besides enabling more optimizations in a library, having a header only library (when it's possible) means an easier way to distribute that library. All the user has to do is download the headers folder and add it to the include path of his/her project. In the case of non header only library things become more complicated. Because you can't mix and match binaries compiled by different compiler and even by the same compiler but with different flags. So you either have to distribute your library with the full source code along with a build tool or have the library compiled in many formats (cpu architecture/OS/compiler/compiler flags combinations)
human preference
Having to write the code once is considered by some (me included) an advantage: both from code documentation perspective and from a maintenance perspective. Others consider separating declaration from definitions is better. One argument is that it achieves separation of interface vs implementation but that is just not the case: in a header you need to have private member declarations even if those aren't part of the interface.
compile time performance
Having all the code in header means duplicating it in every tu. This is a real problem when it comes to compilation time. Heavy header C++ projects are notorious for slow compilation times. It also means that a modification of a function definition would trigger the recompilation of all the tu that include it, as opposed to just 1 tu in the case of definition in source code. Precompiled headers try to solve this problem but the solutions are not portable and have problems of their own.
If the same function definition appears in multiple compilation units then it needs to be inline otherwise you get a linking error.
You need the inline keyword e.g. for function templates if you want to make them available using a header because then their definition also has to be in the header.
The below statement might be a bit oversimplified because compilers and linkers are really complex nowadays, but to get a basic idea it is still valid.
A cpp file and the headers included by that cpp file form a compilation unit and each compilation unit is compiled individually. Within that compilation unit, the compiler can do many optimizations like potentially inlining any function call (no matter if it is a member or a free function) as long as the code still behaves according to the specification.
So if you place the function definition in the header you allow the compiler to know the code of that function and potentially do more optimizations.
If the definition is in another compilation unit the compiler can't do much and optimizations then can only be done at linking time. Link time optimizations are also possible and are indeed also done. And while link-time optimizations became better they potentially can't do as much as the compiler can do.
Header only libraries have the big advantage that you do not need to provide project files with them, the one how wants to use that library just copies the headers to their projects and includes them.
In short:
You're writing a library and you want it to be header-only, to make its use more convenient.
Even if it's not a library, in some cases you may want to keep some of the definitions in a header to make it easier to maintain (whether or not this makes things easier is subjective).
to my knowledge, the use of the inline keyword doesn't guarantee that the function call is inlined
Yes, defining it in a header (as inline) doesn't guarantee inlining. But if you don't define it in a header, it will never be inlined (unless you're using link-time optimizations). So:
You want the compiler to be able to inline the functions, if it decides to.
Also it may the compiler more knowledge about a function:
maybe it never throws, but is not marked noexcept;
maybe several consecutive calls can be merged into one (there's no side effects, etc), but __attribute__((const)) is missing;
maybe it never returns, but [[noreturn]] is missing;
...
there might be templating examples where it's impossible to write the definition in a separate cpp file.
That's true for most templates. They automatically behave as if they were inline, so you don't need to specify it explicitly. See Why can templates only be implemented in the header file? for details.
I have a function that I need inlined in a tight loop in C++11
I want the function to be implemented in a separate file from the header and still force the it to be inlined everywhere it is used. Also, I want to compile with both clang, GCC and the Intel compiler.
To flesh out the requirement. I am looking for a macro that would allow me to do something like:
#define force_inline <something here>
In headers:
force_inline void foo();
And I should be able to do this in the implementation file:
void foo() {... Code.. }
Just to be clear, I do not want to put code in my headers. I want them to only contain the declaration of the function.
Is there a way to achieving inlining with a macro that works on all those compilers?
The best solution I have so far is this macro:
#define forceinline inline __attribute__((always-inline))
It seems that ICC needs both inline (which has nothing to do with inlining the code) and the full implementation in the header to guarantee inlining of the function.
PS: Yes, I have measured my performance and I know for a fact that it is faster to have the function inlined than not. And no, the compiler does not do it for me.
By definition, an inline function has its code included (by the compiler) at each place it's called.
It means the compiler needs to be able to access the function's code when it builds the callers compilation unit. This is technically feasible, but not easy and hardly scalable. Note that if you distribute only your header and a library, it means the compiler using your component has to retrieve the code from the library !!
If implemented by a compiler, it means that you won't benefit from having code out of header as much as for regular functions (changing the CPP file will require recompiling all the files depending on the header, even if it didn't change). The only benefit would be to have a header that doesn't contain code (which is still a good thing).
The only currently available solution that I'm aware of is the link time optimization of GCC, therefore not meeting your requirement of working with clang and icc: https://gcc.gnu.org/wiki/LinkTimeOptimization
Maybe something similar exists for those compiler with specific options, which would need to do compiler dependant code to support it.
Solution 1:
You could keep a "clean class" without any implementation in the header and put the inline functions outside of the class (but still inside the header). You still have definitions in the header but it's clearly separated from the declaration so it hurts less the readability. (This is my prefered solution personally)
Solution 2:
Another way to mitigate your issue, if you really want only the declarations in the header, is to separate your code in 3 files instead of 2:
- a .h file containing only the interface
- a .i file containing inline functions and included by the .h file
- a .cpp/.cc file containing the rest of the code
Obviously this has drawbacks too as your code is now separated in two different files ...
Please tell me if you see an issue that I missed and that you see in these propositions.
I'm working on a very tiny piece of C/C++ source code. The program reads input values from stdin, processes them with an algorithm and writes the results to stdout.
I would just implement all that in a single file, but I also want test cases for the algorithm (not the input/output reading), so I have the following files in my project:
main.cpp
sort.hpp
sort_test.cpp
I implement the algorithm in sort.hpp right away, no sort.cpp. It's rather short and doesn't have any dependencies.
Would you say that, in some cases, functions defined in headers are okay, even if they are sophisticated algorithms and not just simple accessors/mutators? Or is there a reason I should avoid this? When should I move code from header to source file?
There is nothing wrong with having functions in header files, as long as you understand the tradeoff. Putting them in a header file means they'll have to be compiled (and recompiled) in any translation unit that includes the header. (and they have to be declared inline, or you will get linker errors.)
In projects with many translation units, that may add up to a noticeable slowdown in compile times, if you do it a lot.
On the other hand, it ensures that the function definition is visible everywhere the function is called -- and that means that it can be trivially inlined, so the resulting program may run faster.
And finally, with function templates, you typically have no realistic alternative. The definition must be visible at the call site, and the only practical way to achieve that is to put it in a header.
A final consideration is that header-only libraries are easier to deploy and use. You don't need to link against anything, you don't have to worry about ABI's or anything else. You just add the headers to your project, include them and off you go.
Quite a few popular libraries use a header-only strategy.
When you put functions in headers you have to make sure to declare them inline. This is required to avoid a duplicate definition warning when more than one .cpp file include that header file. Generally you should only put small functions inside header files because it will be compiled for each cpp file that includes the header which will slow down compilation time and also results in code bloat; a larger executable file.
It's OK to put any function in the header as long as it's inline. Things such as functions defined inside class { } and templates are implicitly inline.
If the resulting application becomes too large, then optimize the code size. Optimizing before there is a problem is an anti-pattern, especially when there is a benefit to doing it "your way," and the fix is as simple as moving from one file to another and erasing inline.
Of course, if you want to distribute the code as a library, then deciding between a header, static library, or dynamic library binary is an important decision affecting the users.
The vast majority of the boost libraries are header-only, so I'd say: Yes, this is an established and accepted practice. Just don't forget to inline.
That really is a stile choice. But putting it in the header does mean that it will be inline code rather than a function. If you wanted that same functionality, you could use the inline keyword:
inline int max(int a, int b)
{
return (a > b) ? a : b;
}
http://en.wikipedia.org/wiki/Inline_function
The reason you should avoid this in general (for non inline functions) is because multiple source files will be including your header, creating linker errors.
It doesn't matter if you have a pramga once or similar trick - the duplication will show up if you have more than one compilation unit (e.g. cpp files) including the same header.
If you wish to inline the function, it MUST be in the header else it can't get inlined.
If you publish a header with your libraries and the header has some sort of implementation in it, you can be sure that after a few years if you change the implementation and it doesn't work exactly the same way as it did before, some peoples code will break since thay will have come to rely on the implementation they saw in the header. Yeah i know one should not do it but many people do look in header for the implementation and other behaviour they can exploit/use in a not intended way to overcome some problem they are having.
If you are planning to use templates then you have no choice but to put it all in header. (this might not be necessary if you compiler supports export templates but there is only 1 i know of).
Its ok to have the implementation in the header. It depends on what you need. If you separate the definition to a different file then the compiler will create symbols with external linkage if you dont want that you can define the functions inside the header itself. But you would be wasting some amount of memory for the code segment. If you include this header file in two different files then both files codes segment will have this function definition.
If other header file is going to have a function with similar name then its going to be a problem. Then you have to use inline.
When my cpp file uses #include to add some header, does my final program's size gets bigger? Header aren't considered as compilation units, but the content of the header file is added to the actual source file by the preprocessor, so will the size of the output file (either exe or dll) be affected by this?
Edit: I forgot to mention that the question is not about templates/inline functions. I meant what will happen if I place an #include to a header that doesn't have any implementation detail of functions. Thanks.
It depends on the contents, and how your compiler is implmented. It is quite possible that if you don't use anything in the header your compiler will be smart enough to not add any of it to your executable.
However, I wouldn't count on that. I know that back in the VC++ 6 days we discovered that meerly #including Windows.h added 64K to the excecutable for each source file that did it.
You clarified that:
[The header has no] templates/inline functions... doesn't have any implementation detail of functions.
Generally speaking, no, adding a header file won't affect program size.
You could test this. Take a program that already builds, and check the executable size. Then go into each .cpp file and include a standard C or C++ header file that isn't actually needed in that file. Build the program and check the executable size again - it should be the same size as before.
By and large, the only things that affect executable size are those that cause the compiler to either generate different amounts of code, global/static variable initializations, or DLLs/shared library usages. And even then, if any such items aren't needed for the program to operate, most modern linkers will toss those things out.
So including header files that only contain things like function prototypes, class/struct definitions without inlines, and definitions of enums shouldn't change anything.
However, there are certainly exceptions. Here are a few.
One is if you have an unsophisticated linker. Then, if you add a header file that generates things the program doesn't actually need, and the linker doesn't toss them out, the executable size will bloat. (Some people deliberately build linkers this way because the link time can become insanely fast.)
Many times, adding a header file that adds or changes a preprocessor symbol definition will change what the compiler generates. For instance, assert.h (or cassert) defines the assert() macro. If you include a header file in a .c/.cpp file that changes the definition of the NDEBUG preprocessor symbol, it will change whether assert() usages generate any code, and thus change the executable size.
Also, adding a header file that changes compiler options will change the executable size. For instance, many compilers let you change the default "packing" of structs via something like a #pragma pack line. So if you add a header file that changes structure packing in a .c/.cpp file, the compiler will generate different code for dealing with structs, and hence change the executable size.
And as someone else pointed out, when you're dealing with Visual C++/Visual Studio, all bets are off. Microsoft has, shall we say, a unique perspective around their development tools which is not shared by people writing compiler systems on other platforms.
With modern compilers included files only affect the binaries size if they contain static data or if you use normal or inline function that are defined in them.
Yes, because for example inline functions can be defined in header files, and the code of those inline functions will ofcourse be added to your program's code when you call those functions. Also template instantiations will be added to the code of your program.
And you can also define global variables in header files (although I wouldn't recommend it). If you do, you should surround them with #ifdef/#end blocks so that they don't get defined in more than one compilation unit (or the linker would complain). In any case, this would increase the program's size.
Remember, #define sentences can bloat the code at compile time into a huge, yet functional compiled file.
For headers that are entirely declarative (as they generally should be), no. However the pre-processor and compiler have to take time to parse the headers, so headers can increase compile time; especially large and deeply nested ones such as - which is why some compilers use 'precompiled headers'.
Even inline and template code does not increase code size directly. If the template is never instantiated or an inline function not called, the code will not be generated. However if it is called/instantiated, code size can grow rapidly. If the compiler actually inlines the code (a compiler is not obliged to do so, and most don't unless forced to), the code duplication may be significant. Even if it is not truly inlined by the compiler, it is still instantiated statically in every object module that references it - it takes a smart linker to remove duplicates, and that is not a given - if separate object files were compiled with different options, inline code from the same source may not generate identical code in each object file, so would not even be duplicated. In the case of templates, and separate instantiation will be created for each type in is invoked for.
It's good practice to limit the #includes in a file to those that are necessary. Besides affecting the executable size, having extra #includes will cause a larger list of compile-time dependencies which will increase your build-time if you change a commonly #included header file.
In C++, declaration and definition of functions, variables and constants can be separated like so:
function someFunc();
function someFunc()
{
//Implementation.
}
In fact, in the definition of classes, this is often the case. A class is usually declared with it's members in a .h file, and these are then defined in a corresponding .C file.
What are the advantages & disadvantages of this approach?
Historically this was to help the compiler. You had to give it the list of names before it used them - whether this was the actual usage, or a forward declaration (C's default funcion prototype aside).
Modern compilers for modern languages show that this is no longer a necessity, so C & C++'s (as well as Objective-C, and probably others) syntax here is histotical baggage. In fact one this is one of the big problems with C++ that even the addition of a proper module system will not solve.
Disadvantages are: lots of heavily nested include files (I've traced include trees before, they are surprisingly huge) and redundancy between declaration and definition - all leading to longer coding times and longer compile times (ever compared the compile times between comparable C++ and C# projects? This is one of the reasons for the difference). Header files must be provided for users of any components you provide. Chances of ODR violations. Reliance on the pre-processor (many modern languages do not need a pre-processor step), which makes your code more fragile and harder for tools to parse.
Advantages: no much. You could argue that you get a list of function names grouped together in one place for documentation purposes - but most IDEs have some sort of code folding ability these days, and projects of any size should be using doc generators (such as doxygen) anyway. With a cleaner, pre-processor-less, module based syntax it is easier for tools to follow your code and provide this and more, so I think this "advantage" is just about moot.
It's an artefact of how C/C++ compilers work.
As a source file gets compiled, the preprocessor substitutes each #include-statement with the contents of the included file. Only afterwards does the compiler try to interpret the result of this concatenation.
The compiler then goes over that result from beginning to end, trying to validate each statement. If a line of code invokes a function that hasn't been defined previously, it'll give up.
There's a problem with that, though, when it comes to mutually recursive function calls:
void foo()
{
bar();
}
void bar()
{
foo();
}
Here, foo won't compile as bar is unknown. If you switch the two functions around, bar won't compile as foo is unknown.
If you separate declaration and definition, though, you can order the functions as you wish:
void foo();
void bar();
void foo()
{
bar();
}
void bar()
{
foo();
}
Here, when the compiler processes foo it already knows the signature of a function called bar, and is happy.
Of course compilers could work in a different way, but that's how they work in C, C++ and to some degree Objective-C.
Disadvantages:
None directly. If you're using C/C++ anyway, it's the best way to do things. If you've got a choice of language/compiler, then maybe you can pick one where this is not an issue. The only thing to consider with splitting declarations into header files is to avoid mutually recursive #include-statements - but that's what include guards are for.
Advantages:
Compilation speed: As all included files are concatenated and then parsed, reducing the amount and complexity of code in included files will improve compilation time.
Avoid code duplication/inlining: If you fully define a function in a header file, each object file that includes this header and references this function will contain it's own version of that function. As a side-note, if you want inlining, you need to put the full definition into the header file (on most compilers).
Encapsulation/clarity: A well defined class/set of functions plus some documentation should be enough for other developers to use your code. There is (ideally) no need for them to understand how the code works - so why require them to sift through it? (The counter-argument that it's may be useful for them to access the implementation when required still stands, of course).
And of course, if you're not interested in exposing a function at all, you can usually still choose to define it fully in the implementation file rather than the header.
The standard requires that when using a function, a declaration must be in scope. This means, that the compiler should be able to verify against a prototype (the declaration in a header file) what you are passing to it. Except of course, for functions that are variadic - such functions do not validate arguments.
Think of C, when this was not required. At that time, compilers treated no return type specification to be defaulted to int. Now, assume you had a function foo() which returned a pointer to void. However, since you did not have a declaration, the compiler will think that it has to return an integer. On some Motorola systems for example, integeres and pointers would be be returned in different registers. Now, the compiler will no longer use the correct register and instead return your pointer cast to an integer in the other register. The moment you try to work with this pointer -- all hell breaks loose.
Declaring functions within the header is fine. But remember if you declare and define in the header make sure they are inline. One way to achieve this is to put the definition inside the class definition. Otherwise prepend the inline keyword. You will run into ODR violation otherwise when the header is included in multiple implementation files.
There are two main advantages to separating declaration and definition into C++ header and source files. The first is that you avoid problems with the One Definition Rule when your class/functions/whatever are #included in more than one place. Secondly, by doing things this way, you separate interface and implementation. Users of your class or library need only to see your header file in order to write code that uses it. You can also take this one step farther with the Pimpl Idiom and make it so that user code doesn't have to recompile every time the library implementation changes.
You've already mentioned the disadvantage of code repetition between the .h and .cpp files. Maybe I've written C++ code for too long, but I don't think it's that bad. You have to change all user code every time you change a function signature anyway, so what's one more file? It's only annoying when you're first writing a class and you have to copy-and-paste from the header to the new source file.
The other disadvantage in practice is that in order to write (and debug!) good code that uses a third-party library, you usually have to see inside it. That means access to the source code even if you can't change it. If all you have is a header file and a compiled object file, it can be very difficult to decide if the bug is your fault or theirs. Also, looking at the source gives you insight into how to properly use and extend a library that the documentation might not cover. Not everyone ships an MSDN with their library. And great software engineers have a nasty habit of doing things with your code that you never dreamed possible. ;-)
Advantage
Classes can be referenced from other files by just including the declaration. Definitions can then be linked later on in the compilation process.
You basically have 2 views on the class/function/whatever:
The declaration, where you declare the name, the parameters and the members (in the case of a struct/class), and the definition where you define what the functions does.
Amongst the disadvantages are repetition, yet one big advantage is that you can declare your function as int foo(float f) and leave the details in the implementation(=definition), so anyone who wants to use your function foo just includes your header file and links to your library/objectfile, so library users as well as compilers just have to care for the defined interface, which helps understanding the interfaces and speeds up compile times.
One advantage that I haven't seen yet: API
Any library or 3rd party code that is NOT open source (i.e. proprietary) will not have their implementation along with the distribution. Most companies are just plain not comfortable with giving away source code. The easy solution, just distribute the class declarations and function signatures that allow use of the DLL.
Disclaimer: I'm not saying whether it's right, wrong, or justified, I'm just saying I've seen it a lot.
One big advantage of forward declarations is that when used carefully you can cut down the compile time dependencies between modules.
If ClassA.h needs to refer to a data element in ClassB.h, you can often use just a forward references in ClassA.h and include ClassB.h in ClassA.cc rather than in ClassA.h, thus cutting down a compile time dependency.
For big systems this can be a huge time saver on a build.
Disadvantage
This leads to a lot of repetition. Most of the function signature needs to be put in two or more (as Paulious noted) places.
Separation gives clean, uncluttered view of program elements.
Possibility to create and link to binary modules/libraries without disclosing sources.
Link binaries without recompiling sources.
When done correctly, this separation reduces compile times when only the implementation has changed.