All my quetions are related to vc++ compiler but I guess other c++ compilers have the same behavior.
Are the precompiled headers a preprocessor-related stuff or this is all about the compilation process? Or both? I have several guess:
PCH-engine only expands MACRO-definitions and nested headers and translates them into binary format (pch file). In this case all source-files (I mean cpp/hpp which may be included in PCH too) will being recompiled in EVERY source files in project. Or not?
All source-files will be compiled only once and pulled into single obj-file? For example, how many times will be compiled variant library in this example? I.e. only once - in PCH or two times - not in PCH but in both *.cpp files or three times - in PCH and both *.cpp files? and why?
//stdafx.h
#include <boost/variant/variant.hpp>
//test1.cpp
#include "stdafx.h"
#include <boost/variant/variant.hpp>
...
//test2.cpp
#include "stdafx.h"
...
What files should I put in precompiled headers? I guess this is something that used everywhere in project and changed very rarely. What about libraries, boost for example? We use boost only in few source-files, should we put it in PCH?
I have no particular knowledge of VC++'s innards. However, having some knowledge of compiler design and theory, what these so-called "precompiled headers" are can't be anything more than just the result of the initial lexical analysis and tokenization phases of a classical compiler design.
Consider a simple header file that contains the following:
#ifdef FOO
#define BAR 10
#else
#undef FOOBAR
class Foo {
public:
void bar();
};
#include "foobar.h"
#endif
You have to understand that the effect of using a so-called "pre-compiled" header must be identical to using the header file, as is.
Here, you don't really know what this header file is going to do. It all depends on what preprocessor macros are defined when the header file is actually included. You don't know which macros this header file will define. You don't know which macros this header file will undefine. You don't know what other header files this header file will include. You don't really know a lot, here.
The only thing you can conceptually do, to "precompile" a header file, is to pre-parse it. Convert the individual elements of the language, the individual keywords -- like "#ifdef", "class", and all others, into individual binary tokens. Remove any comments, whitespace, etc...
The first phase of compiling a traditional language involves parsing the plain text source into the internal language elements. The lexical analysis and the tokenization phase. After the individual language elements get parsed, then an attempt is made to figure out how the resulting, parsed source code, should get turned into an object module. And that's where 99% of the compiler's work is. The initial lexical analysis phase is not really a lot, but that's pretty much all you can do to "precompile" the source code, and save the internal binary representation of the tokenized source, so that this phase can be skipped, when actual code that uses the "precompiled" source is compiled.
I am assuming that VC++ places little, if no restrictions at all, on the contents of precompiled headers. However, if there are some restrictions -- say, the precompiled headers cannot have any conditional preprocessor directives (ifdef/ifndef) except for the classical guards -- than it would be possible to do more work to produce the precompiled headers, and save a little bit more work, here. Other restrictions on the contents of precompiled headers could also result in some additional functionality being shifted into the precompilation phase.
The precompiled header file, which gets compiled due to stdafx.cpp is stdafx.h. A developer would put rarely changed, and frequently needed header files and symbols in this header. Such as Windows.h, vector and some global macros and symbols. By frequently used, I mean across all files in given project.
What's the purpose and helpfulness of such file (PCH)? Well, VC++ compiler will compile entire stdafx.h file, recursively, all headers included all macros and other symbols. For first time, it will take a lot of time, and will produce a PCH file (hence pre-compiled header). On subsequent builds, the elements included through stdafx.h will not be recompiled (as they are already in some binary/pre-compiled format). This reduces build time, and it would vary depending how many elements (headers, symbols etc.) are put through stdafx.h file.
If you have a large codebase, and less of elements in stdafx, you wont get advantage (for example, including common Windows and STL headers everywhere, having externs and typedefs everywhere). Better you find those elements, and put them into stdafx.h, and remove them from header/CPP files. This will greatly reduce overall build times.
This is where you can change it:
I think that MSVC looks for <application_name>.pch for the sole precompiled header for the translation unit and uses that instead of the transcluded header included under #line 1 "c:\\application_name\\stdafx.h" in the preprocessed .i file, if it is available. The precompiled header is probably a serialised AST i.e. the header has been lexed and parsed into an AST representation. It then does not need to lex (or parse) this region of the preprocessed output and just uses the .pch, which contains the lex+parse output of what is written in the preprocessor output under stdafx.h. The preprocessor has already done all other work on stafx.h, such as expanding macros (which don't appear in the .i file / preprocessor output).
Related
First of all i want to say that I read about precompiled headers and I understand that this is an optimization that saves me the time of compiling headers over and over on every built.
I'm reading the documentation of boost and I see that in the instructions they say:
In Configuration Properties > C/C++ > Precompiled Headers, change Use Precompiled Header (/Yu) to Not Using Precompiled Headers
And then they explain it:
There's no problem using Boost with precompiled headers; these instructions merely avoid precompiled headers because it would require Visual Studio-specific changes to the source code used in the examples.
Can some explain me the sentence I marked in bold? which visual studio specific changes they are talking about ? (Here is the link to the documentation I'm reading: http://www.boost.org/doc/libs/1_55_0/more/getting_started/windows.html#pch)
Why and when I would want to turn off the precompiled headers?
what is the difference between "Create" and "Use" in the precompiled header options.
Originally a comment, but I may as well post it. Note: this is specific to VC++:
The bold sentence is their way of saying the samples don't follow the mantra of a unified use-this-lead-in-header-for-pch-generation model. IOW, their samples aren't PCH-friendly, but you can still use pch with boost in your projects if properly configured.
You would turn them off for a variety of reasons. Some source modules, particularly ones from 3rd-parties, don't follow the PCH model of including "the" pch-through-header at their outset. Their samples are such code (and thus the advise to turn them off for their samples). Sometimes source files require different preprocessor configurations only for this files and not all files int he project; another reason to disable PCH for those files.
You typically use a source/header pair to generate "the One"; the precompiled header image. This header file typically includes:
Any system standard lib headers used by your project
3rd-party SDK headers
Just about everything else that is NOT in active development for your project.
The single source file tagged as Create typically includes one line of code : #include "YourHeaderFile.h", where YourHeaderFile.h is the header you filled with stuff from the list above. Tagging it as "Create" through header YourHeaderFile.h tells VC it is the file needed for rebuilding the PCH through that header when compiling other source files. All other source files are tagged as Use (except the ones where PCH is turned off) and should include, as their first line of code, the same #include "TheHeaderFile.h".
In short (hard to believe), <boost> is telling you their samples aren't setup like described above, and as such you should turn PCH off when building them.
When you use pre-compiled headers, you need to do something like:
#include <foo>
#include <bar>
#include <baz>
#pragma hdrstop
// other code here
Everything before the #pragma goes into the precompiled header. Everything after it depends on the precompiled header. The VC++ specific "magic" to make pre-compiled header work is that #pragma.
There's a little more to the story than just that though. To make pre-compiled headers work well, you want to include exactly the same set of headers in exactly the same order in every source file.
That leads to (typically) creating one header that includes all the other common headers and has the #pragma hdrstop right at its end, then including that in all the other source files.
Then, when the compiler does its thing, there are two phases: first you need to create a pre-compiled header. This means running the compiler with one switch. The compiler only looks at what comes before the #pragma hdrstop, builds a symbol table (and such) and puts the data into a .pch file.
Then comes the phase when you do a build using the pre-compiled header. In this phase, the compiler simply ignores everything in the the file up to the #pragma hdrstop. When it gets to that, it reads the compiler's internal state from the .pch file, and then starts compiling that individual file.
This means each source file typically includes a lot of headers it doesn't actually need. That, in turn, means that if you don't use pre-compiled headers, you end up with compilation that's much slower than if you hadn't done anything to support pre-compiled headers at all.
In other words, although the only part that's absolutely required is the #pragma hdrstop, which is fairly innocuous, a great deal more file re-structuring is needed to get much benefit from them--and those changes are likely to actively harmful to compilation time if you're using anything that doesn't support pre-compiled headers (and in the same way VC++ does them at that).
When precompiled headers is on every cpp source file must start with #include "stdafx.h"
So you would turn it off if you do not want to edit all the boost source files.
When precompiled headers is on stdafx.cpp "creates" the precompiled header. All other files "use" the precompiled header.
I was recently looking through the source code of a C++ application and saw that each class did not #include its needed components, but instead #include'd a "Precompiled.h" header. In this Precompiled header was an inclusion of almost every header in the application (not all of them, it was clear that the length and order of the list was deliberate). Essentially, this would mean that every class had an inclusion of every other class in the application.
Is this wise? Why or why not?
Usually if you write an application, you should only include header files which are really needed in cpp files. If you got a really big application, you should use forward declaration in the header and include necessary files in the cpp file. With that, changes in code only affects a minimum on cpp files, so the compiler had only to compile what really has changed.
The situation can totally flip, when it comes to libraries or code which does not change very often. The filename "Precompiled.h" is already a hint. The compiler can precompile the headers to a special object file, often called PCH file. With that, the compiler has not to resolve every include on every compile time. On heavy nested includes, this has high impact on compile speed, because instead of many files to load and parse, there is only one preparsed file. To archive that you have to declare one or more headers as a kind of center file for building a precompiled header. How you do that differs between different compilers.
For example Visual studio uses the header file "stdafx.h" as the center of the precompilation of header files. Because of that, only header files should include there which are not altered very often. Also the file had to be included first in every cpp file. That is because the compiler can not detect any more if a include file which is included before may have influence to the precompiled file. To avoid that, includes before the precompiled includes are not allowed.
Back to your question. Including every file in one header file to use it as precompiled header makes no sense at all, as it conteract the meaning of a precompiled header file.
It is a very bad idea.
For a .cpp file only include the minimum number of #include files.
Thereby when one of them changes the make (or moral equilivant) will not require the whole lot to be recompiled.
Saves lots of time during development.
PS Use forward declarations in preference to #include
Is there some preferred way to organize ones include directives?
Is it better to include the files you need in the .cpp file instead of the .h file? Are the translation units affected somehow?
How about if I need it in both the .h file and .cpp file, should I just include it in the .h file? Will it matter?
Is it a good practice to keep the already defined files in a precompiled header (stdafx.h), for instance std and third party libraries? How about my own files, should I include them in a stdafx.h file along the way as I create them?
// myClass.h
#include <string>
// ^-------- should I include it here? --------
class myClass{
myClass();
~myClass();
int calculation()
};
// myClass.cpp
#include "myClass.h"
#include <string>
// ^-------- or maybe here? --------
[..]
int myClass::calculation(){
std::string someString = "Hello World";
return someString.length();
}
// stdafx.h
#include <string.h>
// ^--------- or perhaps here, and then include stdafx.h everywhere? -------
You should have them at the top of the file, all in one place. This is what everyone expects. Also, it is useful to have them grouped, e.g. first all standard headers, then 3rd-party headers (grouped by library), then your own headers. Keep this order consistent throughout the project. It makes it easier to understand dependencies. As #James Kanze points out, it is also useful to put the header that declares the content first. This way you make sure that it works if included first (meaning it does no depend on any includes that it does not include itself).
Keep the scope as small as possible, so that a change in the header affects the least number of translation-units. This means, whenever possible include it in the cpp-file only. As #Pedro d'Aquino commented, you can reduce the number of includes in a header by using forward declarations whenever possible (basically whenever you only use references or pointers to a given type).
Both - explicit is better than implicit.
After some reading, I believe you should only include headers in the PCH if you are confident that they do not change anymore. This goes for all standard headers as well as (probably) third party libraries. For your own libraries, you be the judge.
This article on Header file include patterns should be helpful for you.
Is there some preferred way to organize ones include directives?
Yes, you can find them in the above article.
Is it better to include the files you need in the .cpp file instead of
the .h file? Are the translation units
affected somehow?
Yes, it is better to have them in .cpp. Even, if a defined type is required in definition of another type, you can use forward declaration.
How about if I need it in both the .h file and .cpp file, should I just
include it in the .h file? Will it
matter?
Only in .h file, but it is suggested to forward declare in header files, and include in .cpp files.
Is it a good practice to keep the already defined files in a precompiled
header (stdafx.h), for instance std
and third party libraries? How about
my own files, should I include them in
a stdafx.h file along the way as I
create them?
I personally have not used precompiled headers, but there has been a discussion on them on Stackoverflow earlier:
Precompiled Headers? Do we really need them
Is there some preferred way to organize ones include directives?
No common conventions. Some suggest alphabet-sorting them, I personally dislike it and prefer keeping them logically grouped.
Is it better to include the files you need in the .cpp file instead of the .h file?
In general, yes. It reduces the count of times that the compiler needs to open and read the header file just to see the include guards there. That may reduce overall compilation time.
Sometimes it's also recommended to forward-declare as much classes as possible in the headers and actually include them only in .cpp's, for the same reason. The "Qt people" do so, for example.
Are the translation units affected somehow?
In semantic sense, no.
How about if I need it in both the .h file and .cpp file, should I just include it in the .h file? Will it matter?
Just include it in the header.
Is it a good practice to keep the already defined files in a precompiled header (stdafx.h), for instance std and third party libraries? How about my own files, should I include them in a stdafx.h file along the way as I create them?
Precompiled headers can significantly reduce compilation times. For example: one of my projects that includes boost::spirit::qi compiles in 20 secs with PCH on, and 80 secs — without. In general, if you use some heavily template-stuffed library like boost, you'd want to utilise the advantage of PCH.
As for the question in your code sample: since you don't use std::string in the header, it's better to include it in the .cpp file. It's alright to #include <string> in stdafx.h too — but that will just add a little bit of complexity to your project and you'll hardly notice any compilation speed-up.
(4) I wouldn't recommend to include any additional files into stdafx.h. or similar "include_first.h" files. Direct including into cpp or particular h files allow you to express dependencies of your code explicitly and exclude redundant dependencies. It is especialy helpful when you decide to decompose monolithic code into a few libs or dll's. Personally, I use files like "include_first.h" (stdafx.h) for configuration purpose only (this file contains only macro definitions for current application configuration).
It is possible to provide precompiled headers for your own files by marking another file to stop precompilation instead of stdafx.h (for instance, you can use special empty file named like "stop_pch.h").
Note, precompiled headers may not work properly for some kinds of sofisticated usage of the preprocessor (particulary, for some technics used in BOOST_PP_* )
From the performance point of view:
Changing any of the headers included from stdafx.h will trigger a new precompilation, so it depends on how "frozen" the code is. External libraries are typical candidates for stdafx.h inclusion, but you can certainly include your own libraries as well - it's a tradeoff based on how often you expect to change them.
Also, with the Microsoft compiler you can put this at the top of each header file:
#pragma once
This allows the compiler to fully skip that file after the first occurrence, saving I/O operations. The traditional ifndef/define/endif pattern requires opening and parsing the file every time it's included, which of course takes some time. It can certainly accumulate and get noticeable!
(Make sure to leave the traditional guards in there, for portability.)
It might be important to notice that the order of classes in Translation Unit need to be correct or some c++ features are just disabled and results in a compile-time error.
Edit: Adding examples:
class A { };
class B { A a; }; // order of classes need to be correct
What order should include files be specified, i.e. what are the reasons for including one header before another?
For example, do the system files, STL, and Boost go before or after the local include files?
I don't think there's a recommended order, as long as it compiles! What's annoying is when some headers require other headers to be included first... That's a problem with the headers themselves, not with the order of includes.
My personal preference is to go from local to global, each subsection in alphabetical order, i.e.:
h file corresponding to this cpp file (if applicable)
headers from the same component,
headers from other components,
system headers.
My rationale for 1. is that it should prove that each header (for which there is a cpp) can be #included without prerequisites (terminus technicus: header is "self-contained"). And the rest just seems to flow logically from there.
The big thing to keep in mind is that your headers should not be dependent upon other headers being included first. One way to insure this is to include your headers before any other headers.
"Thinking in C++" in particular mentions this, referencing Lakos' "Large Scale C++ Software Design":
Latent usage errors can be avoided by ensuring that the .h file of a component parses by itself – without externally-provided declarations or definitions... Including the .h file as the very first line of the .c file ensures that no critical piece of information intrinsic to the physical interface of the component is missing from the .h file (or, if there is, that you will find out about it as soon as you try to compile the .c file).
That is to say, include in the following order:
The prototype/interface header for this implementation (ie, the .h/.hh file that corresponds to this .cpp/.cc file).
Other headers from the same project, as needed.
Headers from other non-standard, non-system libraries (for example, Qt, Eigen, etc).
Headers from other "almost-standard" libraries (for example, Boost)
Standard C++ headers (for example, iostream, functional, etc.)
Standard C headers (for example, cstdint, dirent.h, etc.)
If any of the headers have an issue with being included in this order, either fix them (if yours) or don't use them. Boycott libraries that don't write clean headers.
Google's C++ style guide argues almost the reverse, with really no justification at all; I personally tend to favor the Lakos approach.
I follow two simple rules that avoid the vast majority of problems:
All headers (and indeed any source files) should include what they need. They should not rely on their users including things.
As an adjunct, all headers should have include guards so that they don't get included multiple times by over-ambitious application of rule 1 above.
I also follow the guidelines of:
Include system headers first (stdio.h, etc) with a dividing line.
Group them logically.
In other words:
#include <stdio.h>
#include <string.h>
#include "btree.h"
#include "collect_hash.h"
#include "collect_arraylist.h"
#include "globals.h"
Although, being guidelines, that's a subjective thing. The rules on the other hand, I enforce rigidly, even to the point of providing 'wrapper' header files with include guards and grouped includes if some obnoxious third-party developer doesn't subscribe to my vision :-)
To add my own brick to the wall.
Each header needs to be self-sufficient, which can only be tested if it's included first at least once
One should not mistakenly modify the meaning of a third-party header by introducing symbols (macro, types, etc.)
So I usually go like this:
// myproject/src/example.cpp
#include "myproject/example.h"
#include <algorithm>
#include <set>
#include <vector>
#include <3rdparty/foo.h>
#include <3rdparty/bar.h>
#include "myproject/another.h"
#include "myproject/specific/bla.h"
#include "detail/impl.h"
Each group separated by a blank line from the next one:
Header corresponding to this cpp file first (sanity check)
System headers
Third-party headers, organized by dependency order
Project headers
Project private headers
Also note that, apart from system headers, each file is in a folder with the name of its namespace, just because it's easier to track them down this way.
I recommend:
The header for the .cc module you're building. (Helps ensure each header in your project doesn't have implicit dependencies on other headers in your project.)
C system files.
C++ system files.
Platform / OS / other header files (e.g. win32, gtk, openGL).
Other header files from your project.
And of course, alphabetical order within each section, where possible.
Always use forward declarations to avoid unnecessary #includes in your header files.
I'm pretty sure this isn't a recommended practice anywhere in the sane world, but I like to line system includes up by filename length, sorted lexically within the same length. Like so:
#include <set>
#include <vector>
#include <algorithm>
#include <functional>
I think it's a good idea to include your own headers before other peoples, to avoid the shame of include-order dependency.
This is not subjective. Make sure your headers don't rely on being #included in specific order. You can be sure it doesn't matter what order you include STL or Boost headers.
First include the header corresponding to the .cpp... in other words, source1.cpp should include source1.h before including anything else. The only exception I can think of is when using MSVC with pre-compiled headers in which case, you are forced to include stdafx.h before anything else.
Reasoning: Including the source1.h before any other files ensures that it can stand alone without it's dependencies. If source1.h takes on a dependency on a later date, the compiler will immediately alert you to add the required forward declarations to source1.h. This in turn ensures that headers can be included in any order by their dependants.
Example:
source1.h
class Class1 {
Class2 c2; // a dependency which has not been forward declared
};
source1.cpp
#include "source1.h" // now compiler will alert you saying that Class2 is undefined
// so you can forward declare Class2 within source1.h
...
MSVC users: I strongly recommend using pre-compiled headers. So, move all #include directives for standard headers (and other headers which are never going to change) to stdafx.h.
Include from the most specific to the least specific, starting with the corresponding .hpp for the .cpp, if one such exists. That way, any hidden dependencies in header files that are not self-sufficient will be revealed.
This is complicated by the use of pre-compiled headers. One way around this is, without making your project compiler-specific, is to use one of the project headers as the precompiled header include file.
Several separate considerations are conflated when deciding for a particular include order. Let try to me untangle.
1. check for self-containedness
Many answers suggest that the include order should act as a check that your headers are self-contained. That mixes up the consideration of testing and compilation
You can check separately whether your headers are self-included. That "static analysis" is independent of any compilation process. For example, run
gcc headerfile.h -fsyntax-only
Testing whether your header files are self-contained can easily be scripted/automated. Even your makefile can do that.
No offense but Lakos' book is from 1996 and putting those different concerns together sounds like 90s-style programming to me. That being said, there are ecosystems (Windows today or in the 90s?) which lack the tools for scripted/automated tests.
2. Readability
Another consideration is readability. When you look up your source file, you just want to easily see what stuff has been included. For that your personal tastes and preferences matter most, though typically you either order them from most specific to least specific or the other way around (I prefer the latter).
Within each group, I usually just include them alphabetically.
3. Does the include order matter?
If your header files are self-contained, then the include order technically shouldn't matter at all for the compilation result.
That is, unless you have (questionable?) specific design choices for your code, such as necessary macro definitions that are not automatically included. In that case, you should reconsider your program design, though it might work perfectly well for you of course.
It is a hard question in the C/C++ world, with so many elements beyond the standard.
I think header file order is not a serious problem as long as it compiles, like squelart said.
My ideas is: If there is no conflict of symbols in all those headers, any order is OK, and the header dependency issue can be fixed later by adding #include lines to the flawed .h.
The real hassle arises when some header changes its action (by checking #if conditions) according to what headers are above.
For example, in stddef.h in VS2005, there is:
#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
Now the problem: If I have a custom header ("custom.h") that needs to be used with many compilers, including some older ones that don't provide offsetof in their system headers, I should write in my header:
#ifndef offsetof
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
And be sure to tell the user to #include "custom.h" after all system headers, otherwise, the line of offsetof in stddef.h will assert a macro redefinition error.
We pray not to meet any more of such cases in our career.
I've got a bunch of legacy code that I need to write unit tests for. It uses pre-compiled headers everywhere so almost all .cpp files have a dependecy on stdafx.h which is making it difficult to break dependencies in order to write tests.
My first instinct is to remove all these stdafx.h files which, for the most part, contain #include directives and place those #includes directly in the source files as needed.
This would make it necessary to turn off pre-compiled headers since they are dependent on having a file like stdafx.h to determine where the pre-compiled headers stop.
Is there a way to keep pre-compiled headers without the stdafx.h dependencies? Is there a better way to approach this problem?
Yes, there is a better way.
The problem, IMHO, with the 'wizard style' of precompiled headers is that they encourage unrequired coupling and make reusing code harder than it should be. Also, code that's been written with the 'just stick everything in stdafx.h' style is prone to be a pain to maintain as changing anything in any header file is likely to cause the whole codebase to recompile every time. This can make simple refactoring take forever as each change and recompile cycle takes far longer than it should.
A better way, again IMHO, is to use #pragma hdrstop and /Yc and /Yu. This enables you to easily set up build configurations that DO use precompiled headers and also build configurations that do not use precompiled headers. The files that use precompiled headers don't have a direct dependency on the precompiled header itself in the source file which enables them to be build with or without the precompiled header. The project file determines what source file builds the precompiled header and the #pragma hdrstop line in each source file determines which includes are taken from the precompiled header (if used) and which are taken directly from the source file... This means that when doing maintenance you would use the configuration that doesn't use precompiled headers and only the code that you need to rebuild after a header file change will rebuild. When doing full builds you can use the precompiled header configurations to speed up the compilation process. Another good thing about having the non-precompiled header build option is that it makes sure that your cpp files only include what they need and include everything that they need (something that is hard if you use the 'wizard style' of precompiled header.
I've written a bit about how this works here: http://www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop.html (ignore the stuff about /FI) and I have some example projects that build with the #pragma hdrstop and /Yc /Yu method here: http://www.lenholgate.com/blog/2008/04/practical-testing-16---fixing-a-timeout-bug.html .
Of course, getting from the 'wizard style' precompiled header usage to a more controlled style is often non-trivial...
When you normally use precompiled headers, "stdafx.h" serves 2 purposes. It defines a set of stable, common include files. Also in each .cpp file, it serves as a marker as where the precompiled headers end.
Sounds like what you want to do is:
Leave precompiled header turned on.
Leave the "stdafx.h" include in each .cpp file.
Empty out the includes from "stdafx.h".
For each .cpp file, figure out which includes were needed from the old "stdafx.h". Add these before the #include "stdafx.h" in each .cpp file.
So now you have the minimal set of dependancies, and you still are using precompiled headers. The loss is that you are not precompiling your common set of headers only once. This would be a big hit for a full rebuild. For development mode, where you are only recompiling a few files at a time, it would be less of a hit.
No, there is probably NOT a better way.
However, for a given individual .cpp file, you might decide that you don't need the precompiled header. You could modify the settings for that one .cpp file and remove the stdafx.h line.
(Actually, though, I don't how the pre-compiled header scheme is interferring with the writing of your unit tests).
No. pre-compiled headers relies on a single header included by all sources compiled this way.
you can specify for a single source (or all) not to use pre-compiled headers at all, but that's not what you want.
In the past, Borland C++ compiler did pre-compilation without a specific header. however, if two sources files included the same headers but at different order, they were compiled separately, since, indeed, the order of header files in C++ can matter...
Thus it means that the borland pre-compiled headers did save time only if you very rigidly included sources in the same order, or had a single include file included (first) by all other files... - sounds familiar ?!?!
Yes. The "stdafx.h/stdafx.pch" name is just convention. You can give each .cpp its own precompiled header. This would probably be easiest to achieve by a small script to edit the XML in your .vcproj. Downside: you end up with a large stack of precompiled headers, and they're not shared between TU's.
Possible, but smart? I can't say for sure.
My advice is - don't remove precompiled headers unless you want to make your builds painfully slow. You basically have three options here:
Get rid of precompiled headers (not recommended)
Create a separate library for the legacy code; that way you can build it separately.
Use multiple precompiled headers within a single project. You can select individual C++ files in your Solution Explorer and tell them which precomiled header to use. You would also need to setup your OtherStdAfx.h/cpp to generate a precompiled header.
Pre-compiled headers are predicated on the idea that everything will include the same set of stuff. If you want to make use of pre-compiled headers then you have to live with the dependencies that this implies. It comes down to a trade-off of the dependencies vs the build speed. If you can build in a reasonable time with the pre-compiled headers turned off then by all means do it.
Another thing to consider is that you can have one pch per library. So you may be able to split up your code into smaller libraries and have each of them have a tighter set of dependencies.
I only use pre-compiled headers for the code that needs to include the afx___ stuff - usually just UI, which I don't unit-test. UI code handles UI and calls functions that do have unit-tests (though most don't currently due to the app being legacy).
For the bulk of the code I don't use pre-compiled headers.
G.
Precompiled headers can save a lot of time when rebuilding a project, but if a precompiled header changes, every source file depending on the header will be recompiled, whether the change affects it or not. Fortunately, precompiled headers are used to compile, not link; every source file doesn't have to use the same pre-compiled header.
pch1.h:
#include <bigHeader1.h>
#include ...
pch1.cpp:
#include "pch1.h"
source1.cpp:
#include "pch1.h"
[code]
pch2.h:
#include <bigHeader2.h>
#include ...
pch2.cpp:
#include "pch2.h"
source2.cpp
#include "pch2.h"
[code]
Select pch1.cpp, right click, Properties, Configuration Properties, C/C++, Precompiled Headers.
Precompiled Header : Create(/Yc)
Precompiled Header File: pch1.h
Precompiled Header Output File: $(intDir)pch1.pch
Select source1.cpp
Precompiled Header : Use(/Yu)
Precompiled Header File: pch1.h
Precompiled Header Output File: $(intDir)pch1.pch (I don't think this matters for /Yu)
Do the same thing for pch2.cpp and source2.cpp, except set the Header File and Header Output File to pch2.h and pch2.pch. That works for me.