views:

1186

answers:

3

I understand the purpose and reasoning behind precompiled headers. However, what are the rules when implementing them? From my understanding, it goes something like this:

  1. Set your project up to use precompiled headers with the YU directive.
  2. Create your stdafx.h file and set that to be your precompiled header.
  3. Include this as the top include statement in each of your .h files.

It this correct? Should you exclude the including it in the files that are included within your precompiled header? Currently, I get the following compilation error when following my intuition with this:

error C2857: '#include' statement specified with the /Ycstdafx.h command-line option was not found in the source file

The command-line options are as such:

/Od /I "../External/PlatformSDK/Include" /I ".." /I "../External/atlmfc/Include" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MDd /Yc"stdafx.h" /Fp"....\Output\LudoCore\Debug\LudoCore.pch" /Fo"....\Output\LudoCore\Debug\" /Fd"....\Output\LudoCore\Debug\vc80.pdb" /W4 /WX /nologo /c /ZI /TP /wd4201 /errorReport:prompt

+7  A: 

You stdafx.cpp should include stdafx.h and be built using /Yc"stdafx.h".

Your other *.cpp should be include stdafx.h and be built using /Yu"stdafx.h".

Note the double-quote characters used in the compiler options!

Here's a screenshot of the Visual Studio settings for stdafx.cpp to create a precompiled header:

Here are the corresponding command-line options (which are read-only but reflect the settings specified on other pages; note that the IDE inserts double-quote characters around the filename, in the compiler option):

This is what's in my stdafx.cpp file:

// stdafx.cpp : source file that includes just the standard includes
// CallWinsock.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
ChrisW
Are you saying that this should only be built at command line? In visual studio, I'm not sure how to create something with a certain property right off the bat. It always seems to be just "Add -> New Item -> Header", etc
Chris
Right-click on the cpp file and select "Properties" on the context menu. Among the C++ configuration property pages, there's one for "Precompiled Headers", which you use to specify that this CPP file either creates or uses a precompiled header file.
ChrisW
Thanks for the update. I have done as shown above and still no dice. Here is the command line options with respect to yours above: /Od /I "../External/PlatformSDK/Include" /I ".." /I "../External/atlmfc/Include" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MDd /Yc"stdafx.h" /Fp"..\..\Output\LudoCore\Debug\LudoCore.pch" /Fo"..\..\Output\LudoCore\Debug\\" /Fd"..\..\Output\LudoCore\Debug\vc80.pdb" /W4 /WX /nologo /c /ZI /TP /wd4201 /errorReport:prompt
Chris
What are the contents of your stdafx.cpp (show it by editing and adding it to your original question)? In which directory is your stdafx.h?
ChrisW
If it had contents I would add it to the question, but it is empty, except for including the respective header file right now.
Chris
What exactly does your include statement look like? The error message you cited says that it can't find the include statement in the source file.
ChrisW
#include "stdafx.h" this is the only line of code in stdafx.cpp
Chris
Note that these two files did not generate for me automatically. I manually added them. Is this a part of the problem? (just noticed this might clear some things up)
Chris
Does your stdafx.h exist in the same directory as your stdafx.cpp?
ChrisW
Yes. Also, they are the only two files at the "root" of the project. All of the rest of the files in this project are grouped into folders.
Chris
I don't see what's wrong; you ought to be able to create them (manually) later, and not only when you first create the project. I get the same error message as you, if I comment-out the include statement in my stdafx.cpp, or if I alter the include statement to include a different (but not non-existent) header file.
ChrisW
+1  A: 

Your #include "stdafx.h" should be the first line of each cpp file. It shouldn't be used in the .h files. Other than that you're about right.

Alan
I think his problem is specifying /Ycstdafx.h instead of /Yc"stdafx.h".
ChrisW
A: 

"stdafx" is just a convention. It's in no way mandatory. In a multi-project solution, I've used other setups with multiple pre-compiled headers for different parts. E.g. it may be useful to have one PCH shared by your UI projects, and another one for your database projects.

The relevant components are the X.h file listing precompilable headers, the X.cpp file that includes only X.h (and adds no code itself), and the X.pch file created by compiling X.cpp (and thus X.h) with /Yc.

When you're now compiling Y.cpp file with /Yu"X.pch", the compiler reads and discards everything up to #include "X.h". At that point it replaces its internal state with the state stoerd in X.pch, except for the input stream (remains Y.cpp, with the file pointer set to the next line after #include "X.h").

MSalters