Precompiled headers and normal includes - c++

When using precompiled headers, does it make a difference (or has a bad effect) when I include a header, which I already have included in the precompiled header, also in a regular header?
Or in other words: when I include a header x in another header file and at the same time include x in my precompiled header file, does this prevent the optimization provided by precompiled header to kick in?

No
(In general). What's going to happen is that, during compilation, if you're using precompiled headers, and the compiler spots a header that is already present in the precompiled form, it will opt to use the precompiled form.
In fact, it's good practice to continue using your includes as if you never had precompiled headers on in the first place. This helps in case you turn off precompiled headers in the future or modify the list of headers in it, or someone else decides to do their own out-of-source build that doesn't use PCH.

Precompiled headers are a compile-time optimization. The code must be written as if there was no precompiled headers. The support for those headers can be added entirely using the arguments to the compiler, i.e. by tweaking the build process and adding a "catch-all" header if the build system can't generate one for you (it really should, these days!).
TL;DR: Precompiled headers are a switch you throw in your build script. Nothing more. They should not leak outside of the build scripts.

Related

Precompiled Headers in Header Files

I ran into precompiled headers today for the first time..forever changing my life. I can't believe compiling my C++ code could be that fast. It makes total sense now..
Anyway, one thing that is confusing me is that from what I've read so far, pre-compiled headers only should be added to source files( cpp? ).
In Visual Studio, there is an option under Project Properties->C/C++->Advanced to "Force Include File". I set that compiler option to stdafx.h.
After doing this..I no longer require to include the headers I have added to my stdafx.h, even inside my header files ( source files are supposed to automatically include stdafx.h ). Is this expected behaviour?
I can't find a place that's clear in the distinction between header/source files.
If it does..great but I'm afraid it's another one of those things VC++ lets you get away with but will break in GCC. And yes..it needs to be portable; at least between GCC and VC++.
StdAfx.h really should only be included in source files, not headers. I would suggest you #include "StdAfx.h" first in every cpp and not use the "Force Include File" option. Thats how I do it with my cross-platform projects. For the record, I don't actually use precompiled headers in GCC I just build it normally and it works well.
For some background. The compiler only looks at source files (ie, *.cpp, *.c, etc) and so when it compiles them it has to include every header and compile any code found in the headers as well. The precompiled headers option allows for compiling all of that code (ie, the globally include'd code in StdAfx.h) once so that you don't have to do it all of the time. Thats what StdAfx.cpp is for. The compiler compiles StdAfx.cpp with all of the code included in StdAfx.h once instead of having to do it every time you build.
So, since you include StdAfx.h in every source file as the first item, it doesn't make sense to include it in any of the headers since they will be included AFTER StdAfx.h and thus will have access to all of the code in StdAfx.h. Plus you can then use those headers in other projects without having to worry about having a StdAfx.h around or including the wrong one.
Yes, it is expected behaviour. The Project Properties->C/C++->Advanced to "Force Include File" setting controls Visual C++ compiler option /FI:
This option has the same effect as specifying the file with double
quotation marks in an #include directive on the first line of every
source file
So, it frees you from including the stdafx.h manually.
Although, you can use precompiled headers with GCC and other compilers
The Visual C++'s shortcut behaviour is not portable across other compilers. So, check How to handle stdafx.h in cross-platform code? where ideas for portable solutions are discussed.
Long story short, include stdafx.h manually in your .cpp source files and you should be fine also with GCC (assuming, you will configure your build for GCC to use precompiled headers).
Do not use the "Force Include File" setting (/FI) as it breaks Edit & Continue !
(and MS doesn't seem to want to fix this issue)
See
https://connect.microsoft.com/VisualStudio/feedback/details/668339/vs-2010-sp1-c-edit-and-continue-fails-with-fi
and
https://connect.microsoft.com/VisualStudio/feedback/details/342441/visual-studio-2005-force-includes-breaks-edit-and-continue-with-pre-compiled-headers
#include "stdafx.h" should only be found as the first non-comment line in your source files, not in header files.

Compilation speed improvements include guards vs. precompiled headers

I want to reduce compile time on a large project. Our primary compiler is Visual Studio 2010 but some of the code gets compiled in gcc. We are currently planning to ensure that all our .h files have both include guards as well as #pragma once, this will allow both Visual Studio and gcc to improve compile speed. Previously we had put more headers in the stdafx but we saw disadvantages that if one of those headers was changed, and you compiled a cpp without recompiling the precompiled header that the changes didn't take effect. This often caused us confusion. The current plan is to use precompiled headers for all stable headers or headers out of our control (they won't change) and for everything else use the include guards and #pragma once to help on compilation speed. Is there a reason why this path is poorly planned? Is there a benefit for compilation speed of include guards/#pragma once vs precompiled header or vise-versa that I am missing?
The approach that you are taking is sound, but if changes in one of the headers did not trigger recompilation of the precompiled headers you should check the dependencies in the project.
There are other things that can help in reducing compilation times, like avoiding the includes altogether. That is, use forward declarations in the headers and only include in the cpp files. That will reduce the compile time dependencies and speed up compilation.
I am not a fan of precompiled headers, so I usually just ensure that I include everything that needs including and don't include anything that doesn't.

Precompiled headers: do's and don'ts?

I know precompiled headers are used for speeding up compilations, but are there any do's and don'ts to what files I should include in them? For example, I have a project that uses a lot of boost libs so I just include the boost header files in stdafx.h (I'm using VS2008). Should I include every standard header file in them, too? Will this increase the size of my executeable even if I, for example, include <vector> but never use std::vector? Is it a bad idea to include my own project's header files in stdafx.h?
Generally speaking, every header file that you use across the application and that doesn't change often should go into the precompiled header file. This will speed up compilation because the precompiled header file gets compiled only once.
If you add a header file which changes often, you'll miss the point of the precompiled header file, because this often-changing header file will cause your whole project to recompile, possibly unnecessarily.
Specifically, defines a template class, so if you won't use std::vector, the overhead will not be big. However, I would advise against adding header files - however standard and generic - if you don't really need them. There IS some overhead to the compilation time, the binary size, and it could cause conflicts later in the project, so why add something if you don't really need it?
Pre-compiled headers don't affect the size of your executable, only the compilation speed. Since they are pre-compiled, they don't have to be re-compiled all the time. Windows.h is the primary beneficiary of this feature.
It's a good idea to include the c++ standard header-files and the boost library headers and any other headers from third party libraries that you frequently use. This will not affect the size of your executable.
However, you should not include headers from your own project, since the whole project needs to be rebuild whenever you make changes in these headers.

How to force Visual Studio 2008 to warn about missing header files

I work as the Mac coder on a c++ application which I share with PC coders who use VS2008. When they make changes to a source file that requires an non-included header file they get no warnings, as most of their headers are in a precompiled header. What setting can they use to have them be warned that they failed to add the required include?
Would make my life easier as GCC requires the includes be actually present.
Er... Your question as stated is based on an incorrect premise.
All headers in VS compiler are required to be included. There's no way around it.
Precompiled headers feature does not affect this general principle it any way. The only difference is that in projects that plan to use precompiled headers the headers are normally included indirectly, through a special intermediate header file. Nevertheless, you can't just forget to include some header file, regardless of whether the project is using precompiled headers or not. All headers must be included in all cases, directly or indirectly.
A project that's using precompiled headers will compile perfectly fine on any compiler that knows nothing about any precompiled headers at all.
So, the situation you describe simply cannot happen in practice. If it does, they you must be leaving out some important detail about the problem.
I would make the precompiled headers conditional on a define that is only present on the PC code, or vice versa for the mac code.

What to put in precompiled header? (MSVC)

What are the best candidates for a precompiled header file? Can I put STL and Boost headers there, even though they have templates? And will that reduce compile times?
Also, what are the best IDE settings to reduce compile times?
The quick answer: the STL and Boost headers do indeed belong in the precompiled header file, even though these header files define template classes.
When generating a precompiled header file, a compiler parses the header text (a significant task!), and converts it into a binary format that is optimised for the compiler's benefit.
Even though the template classes will be instantiated when other .cpp files are compiled, they will be instantiated from information in the precompiled header, which is significantly faster for the compiler to read.
(later addition)
One thing that you should not include in a precompiled header are files that are part of your project and are changed frequently, even if every single .CPP file includes these files.
The reason is this - the generation of the precompiled header can take a long time, because the boost, stl and windows libraries are very large.
You might have a simple file (eg "StringDefs.h") that everything uses. If StringDefs.h is included in stdafx.h, and one developer touches StringDefs.h, then every developer has to wait until the entire precompiled header recompiles. It would be much faster if StringDefs.h was left out of the precompiled header, and parsed along with each .CPP file.
One addition to Andrew Shepherd's answer. Use the precompiled header for header files that are external to your project, for files that change infrequently. If you're changing the header files in the current project all the time, it's probably not worth precompiling them.
I've written an article on techniques that reduce the compilation time. Among these techniques a post on precompiled header and its application can be found here. It also has a section on best practices that you may find interesting. CMake scripts that handle it transparently are included.
Put anything in the precompiled header that most of the .cpp files in that project would include anyway. This goes for any header file, really. This allows the compiler to parse these files once, and then reuse that information in all .cpp files in the same project.