Precompiled headers is a technique to reduce compilation time when your #include
s take a long time. Basically, you stuff all your #include
s 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>
you do
//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>
Say compiling "boost/expensive_lib.h"
and "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 #include
s 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.
2: 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++”.
If you enjoyed this post, you can subscribe to my blog, or follow me on Twitter.