Precompiled headers is a technique to reduce compilation time when your
#includes take a long time. Basically, you stuff all your
#includes that rarely change into one single file, which you then include in all your other files. You then tell the compiler to precompile this header, so it takes a negligible amount of time to include later on.
Instead of doing:
//my_file.cpp #include "my_file.h" #include "3rdparty/fancy_stuff.h" #include "boost/expensive_lib.h" #include <string>
//my_file.cpp #include "stdafx.h" //Common name for precompiled headers in Visual Studio #include "my_file.h" //stdafx.h #include "boost/expensive_lib.h" #include "3rdparty/fancy_stuff.h" #include <string>
"3rdparty/fancy_stuff.h" takes three seconds, and you have twenty files including these, the files themselves beeing trivial to compile, taking half a second each. That means compilation will take 20*(3s + 0.5s) = 70 seconds. With precompiled headers, this takes you 20*0.5s + 3s = 13 seconds. And the next time you compile,
stdafx.h is already compiled, so it only takes you 10. That’s roughly an order of magnitude quicker.
A great improvement, no?
While it improves compilation time, it certainly does not improve readability and maintainability. Personally, I think of it as a bit of an ugly hack.
There are at least three problems with this:
1: As your project evolves,
stdafx.h can get quite crowded. Come refactoring-time, you want to remove
#includes which are no longer in use. While this can be challenging enough in a large
cpp-file, imagine having one file holding includes from tens of others. Now you don’t only have to look through the current file to see if a certain
#include can be removed, you have to look through you entire project.
stdafx.h now has to be the first header you include, which violates best pratice for include order.
3: Precompiled headers make .cpp-files quicker to compile. But what about when a header itself depends on other expensive headers? Normally, these need to be included in the header itself, leading to long compilation time for everyone using this header. A popular technique with precompiled headers is to not include these in the header. Since all .cpp-files will have included
stdafx.h before including this header, everything will be ok. In addition to the problems laid out in 2, this poses a bigger problem when this header-file is included in .cpp-files in other projects, or even other solutions. If someone now wants to include my
my_header.h, it is suddenly their responsibility to include headers that
my_header.h uses internally.
That about sums it up. Consider precompiled headers added to my list of “necessary evils in C++”.