# StdAfx.h

This article is meant for those programmers who are only getting started with the Visual Studio environment, and trying to compile their C++ projects under it. Everything can look strange and complicated in an unfamiliar environment, and novices are especially irritated by the stdafx.h file that causes strange errors during compilation. Pretty often it all ends in them diligently turning off all precompiled headers in every project. We’ve written this article in order to help Visual Studio newcomers to figure it all out.

## The purpose of precompiled headers

Precompiled headers are intended to speed up project builds. When getting started with Visual C++, programmers usually try it on very small projects that cannot show the performance gain from using precompiled headers. Both with and without them, the program seems to take the same time to compile. This is just what confuses the user; he doesn’t see any use in this option, and concludes that it is needed for some specific tasks and he will never need it. This delusion may last for years.

Precompiled headers are actually a very useful technology. The benefit can be seen even with a project of just a few dozen files. Using such heavy libraries as a boost will make the performance gain especially evident.

If you examine the *.cpp files in your project, you will notice that many of them include the same sets of headers, for example <vector>, <string>, <algorithm>. These headers, in their turn, include other headers, and so on.

All this results in the compiler’s preprocessor doing the same work again and again – it must read the same files many times, insert them into each other, process #ifdef, and expand macros. Because of this, the same operations are repeated a huge number of times.

The amount of work the preprocessor has to do during project compilation can be greatly reduced. The idea is to preprocess a group of files in advance, and then simply insert already prepared text fragments where necessary.

It actually includes a few more steps; instead of simple text, you can store more highly processed information. We don’t know how exactly it is all implemented in Visual C++, but I know that, for instance, you can store text already split into lexemes. This will speed up the compilation process even more.

A file containing precompiled headers has the “.pch” extension. The file name usually coincides with the project name, but you can naturally change this and any other names used, in the settings. The *.pch file may be pretty large, which depends on how many headers are expanded in it. In PVS-Studio, for example, it occupies about 3 Mbytes.

The *.pch file is created as a result of the stdafx.cpp file’s compilation. This file is built with the “/Yc” switch which is used specifically to tell the compiler to create precompiled headers. The stdafx.cpp file can contain one line: #include “stdafx.h”.

The most interesting stuff is stored in the “stdafx.h” file. All the header files to be precompiled should be included into it. For example, below is the stdafx.h file we use in PVS-Studio (the text is abridged for the article):

#include "VivaCore/VivaPortSupport.h"
//For /Wall
#pragma warning(push)
#pragma warning(disable : 4820)
#pragma warning(disable : 4619)
#pragma warning(disable : 4548)
#pragma warning(disable : 4668)
#pragma warning(disable : 4365)
#pragma warning(disable : 4710)
#pragma warning(disable : 4371)
#pragma warning(disable : 4826)
#pragma warning(disable : 4061)
#pragma warning(disable : 4640)
#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <set>
#include <map>
#include <list>
#include <deque>
#include <memory>
#pragma warning(pop) //For /Wall

The “#pragma warning” directives are necessary to get rid of warnings generated on standard libraries.

Now the “stdafx.h” file should be included into all the *.c/*.cpp files. You should also remove from these files, all the headers already included into “stdafx.h”.

But what to do when different files use somewhat similar but still different sets of headers? For example:

• File A: <vector>, <string>
• File B: <vector>, <algorithm>
• File C: <string>, <algorithm>

Should you create individual precompiled headers? Well, you can do that, but you don’t need to.

You only need to create one precompiled header where <vector>, <string>, and <algorithm> will be expanded. The benefit of the preprocessor not having to read numbers of files, and insert them into each other, outweighs the losses on syntax analysis of additional code fragments.

## How to use precompiled headers

When starting a new project, Visual Studio’s Wizard creates two files: stdafx.h, and stdafx.cpp. It is through them that the mechanism of precompiled headers is implemented.

These files can actually have any other names; it’s not the name that matters but the compilation parameters you specify in the project settings.

A *.c/*.cpp file can only use one precompiled header. However, one project may contain a few different precompiled headers. Suppose we have only one for now.

So if you have used the Wizard, the files stdafx.h, and stdafx.cpp are already created for you, and all the necessary compilation switches are also defined.

If you didn’t use the precompiled headers option in your project, let’s find out how to enable it. I suggest the following algorithm:

1. Enable precompiled headers in all configurations for all *.cpp files. It can be done on the “Precompiled Header” tab:
1. Set the value “Use (/Yu)” for the “Precompiled Header” option.
2. Set “stdafx.h” for the “Precompiled Header File” option.
3. Set “$(IntDir)$(TargetName).pch” for the “Precompiled Header Output File” option.
2. Create an stdafx.h file, and add it into the project. We will include those headers we want to be preprocessed in advance into this file.
3. Create an stdafx.cpp file, and add it into the project. This file has only one line: #include “stdafx.h”.
4. Change the settings for the stdafx.cpp file in all configurations; set the value “Create (/Yc)” for the “Precompiled Header” option.

Now we have enabled the precompiled headers option. If we run compilation now, the compiler will create the *.pch file. However, compilation will terminate just a bit later because of errors.

We have set all the *.c/*.cpp files to use precompiled headers, but that’s just the start. We now need to add #include “stdafx.h” into each file.

The “stdafx.h” header must be the very first one to be included into the *.c/*.cpp file. This is obligatory! Otherwise you are guaranteed to get compilation errors.

It really makes sense, if you think about it. When the “stdafx.h” file is included in the very beginning, you can substitute an already preprocessed text into the file. This text stays the same all the time, and is not affected by anything.

And now imagine that we have included some other file prior to “stdafx.h”, and that file contains the line #define bool char. It will make the situation undefined, as we have changed the contents of all the files where “bool” is mentioned. Now you can’t just insert a preprocessed text, as the entire mechanism of “precompiled headers” gets broken. I believe this to be one of the reasons why “stdafx.h” must be included in the first place. Perhaps there are some other reasons too.

## Life hack

Manually typing #include “stdafx.h” into all the *.c/*.cpp files is pretty tiresome and boring. Besides, you will get a new revision in the version control system with lots of files changed. It’s no good doing so.

Third-party libraries included into the project as source files cause some additional troubles. Changing these files won’t make sense. The best solution would be to disable precompiled headers for them, but it’s inconvenient when you use a number of small libraries. You will be constantly stumbling over precompiled headers.

However, there is an easier way to handle precompiled headers. This method is not a universal one, but it did help me in many cases.

Instead of manually adding #include “stdafx.h” into all the files, you may use the “Forced Included File” option.

Go to the “Advanced” settings tab. Select all configurations. In the field “Forced Included File” write the following text:

StdAfx.h;%(ForcedIncludeFiles)

From now on, “stdafx.h” will be automatically included in the beginning of ALL the files to be compiled. PROFIT!

You won’t need to manually add #include “stdafx.h” in the beginning of each and every *.c/*.cpp file anymore – the compiler will do it automatically.

## What to include into stdafx.h

This is a very important question. Mindlessly including every single header into “stdafx.h” will slow down the compilation process instead of speeding it up.

All the files that include “stdafx.h” depend on its contents. Suppose “stdafx.h” includes the file “X.h”. Changing “X.h” just a little bit may cause complete recompilation of the whole project.

Important rule. Make sure your “stdafx.h” file includes only those files that never, or VERY rarely change. The best candidates are headers from system and third-party libraries.

If you include you own project files into “stdafx.h”, be especially careful. Include only those files that change very, very rarely.

If any of the *.h files change once a month, it’s too frequent. In most cases, it takes you more than once to make all the necessary edits in an h-file – usually 2 or 3 times. Completely recompiling the entire project 2 or 3 times is quite an unpleasant thing, isn’t it? Besides, all your colleagues will need to do the same.

But don’t be too fanatical about non-changing files. Include only those headers which you use really often. Including <set> won’t make sense, if you need it in just a couple of files. Instead, simply include this file where needed.

For what may we need several precompiled headers, in one project? Well, it’s a pretty rare situation indeed. But here are couple of examples.

Imagine the project is using both *.c and *.cpp files together. You can’t use a shared *.pch file for them – the compiler will generate an error.

You have to create two *.pch files. One of them is created after compiling the C-file (xx.c), the other after compiling the C++-file (yy.cpp). Accordingly, you should specify in the settings to use one precompiled header for C-files, and another for C++-files.

Note: Don’t forget to set different names for these two *.pch files. Otherwise they will be replacing each other.

Here’s another situation:
One part of the project uses one large library, while the other part uses another large library.

Naturally, different parts of the project should not know about both libraries: there may be (unlucky) overlapping of entities’ names in different libraries.

It is logical to create two precompiled headers, and use them in different parts of the program. As we have already mentioned, you may use any names you like for the files the *.pch files are generated from. Well, even the name of the *.pch file can be changed too. It should all be done very carefully of course, but there’s nothing especially difficult about using two precompiled headers.

## Typical mistakes when using precompiled headers

Now that you have attentively read the text above, you will understand, and eliminate, any errors related to stdafx.h. But I suggest that we quickly review novice programmers’ typical mistakes once again, and investigate the reasons behind them. Practice makes perfect.

### Fatal error C1083: Cannot open precompiled header file: ‘Debug\project.pch’: No such file or directory

You are trying to compile a file that uses a precompiled header, while the corresponding *.pch file is missing. Possible reasons are:

1. The stdafx.cpp file has not been compiled, so the *.pch file is not created yet. This may happen when, for instance, you first clean the solution and then try to compile one *.cpp file (Compile Ctrl-F7). To solve the problem, compile the entire solution, or at least the stdafx.cpp file.
2. No file has been specified in the settings to generate the *.pch file from – that is, the troubles are with the /Yc compilation switch. This problem is common with Visual Studio newcomers trying to use precompiled headers in their project for the first time. To find out how to do it correctly, see the above section “How to use precompiled headers”.

### Fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add ‘#include “stdafx.h”‘ to your source?

The error text says it all if you bother to read it. The file is compiled with the /Yu switch. It means that a precompiled header is to be used, but “stdafx.h” is missing from the file.

You need to add #include “stdafx.h” into the file.

If you can’t do it, do not use the precompiled header for this *.c/*.cpp file. Delete the /Yu switch.

### Fatal error C1853: ‘project.pch’ precompiled header file is from a previous version of the compiler, or the precompiled header is C++ and you are using it from C (or vice versa)

The project contains both C (*.c) and C++ (*.cpp) files. You cannot use a shared precompiled header (*.pch file) for them.

Possible solutions:

1. Disable precompiled headers for all the C-files. Practice shows that *.c files are preprocessed several times quicker than *.cpp ones. If you have just a few *.c files, you won’t lose out on performance by disabling precompiled headers for them.
2. Create two precompiled headers. The first one should be generated from stdafx_cpp.cpp, stdafx_cpp.h; the second from stdafx_c.c, stdafx_c.h. Accordingly, you should use different precompiled headers for the *.c and *.cpp files. The names of the *.pch files must also be different, of course.

### The compiler misbehaves when using precompiled headers

You must have done something wrong. For example, the line #include “stdafx.h” is not the first one in the file.

Take a look at this example:

int A = 10;
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[]) {
return A;
}

This code will fail to compile, the compiler generating a seemingly strange error message:

error C2065: 'A' : undeclared identifier

It thinks that all text before #include “stdafx.h” (including this line) is a precompiled header. When compiling the file, the compiler will substitute the text before #include “stdafx.h” with the text from the *.pch file. It will result in losing the line “int A = 10”.

The correct code should look like this:

#include "stdafx.h"
int A = 10;
int _tmain(int argc, _TCHAR* argv[]) {
return A;
}

One more example:

#include "my.h"
#include "stdafx.h"

The contents of the file “my.h” won’t be used. As a result, you won’t be able to use the functions declared in this file. Such behavior confuses programmers a lot. They try to “cure” it by completely disabling precompiled headers, and then come up with stories about how buggy Visual C++ is. Remember one thing: a compiler is one of the least buggy tools. In 99.99% of all cases, it’s not the compiler you should be angry with, but mistakes in your own code (Proof).

To avoid such troubles, make sure you add #include “stdafx.h” at the very beginning of the file ALL THE TIME. Well, you can leave comments before #include “stdafx.h”; they don’t take part in compilation anyway.

Another way is to use Forced Included File. See the section “Life hack” above.

### The entire project keeps completely recompiling when using precompiled headers

You have added into stdafx.h a file that you keep regularly editing. Or you could have included an auto-generated file by mistake.

Closely examine the contents of the “stdafx.h” file: it must contain only headers that never or very rarely change. Keep in mind that while certain included files do not change themselves, they may contain references to other *.h files that do.

### Something strange going on

You may sometimes come across an issue when an error doesn’t disappear, even after fixing the code. The debugger reports something strange.

This issue may relate to the *.pch file. For some reason the compiler doesn’t notice that one of the header files has been changed, so it doesn’t recompile the *.pch file, and keeps inserting previously generated text. It might have been caused by some faults related to the time of file modification.

This is an EXTREMELY rare situation. But it is possible, and you should be aware of it. Personally I have faced this issue only 2 or 3 times during the many years of my career. It can be solved by complete full project recompilation.

### Conclusion

As you can see, working with precompiled headers is pretty easy. Programmers that try to use them and constantly face “compiler’s numerous bugs”, just don’t understand the working principles behind this mechanism. We hope this article has helped you to overcome that misunderstanding.

Precompiled headers are a very useful option, which allow you to significantly enhance project compilation speed.

## 11 thoughts on “StdAfx.h”

1. matt

Thanks for this insight. I never really learned to use these, but I think I’ll go play around with it now. One drawback I can see already, though. If it doesn’t take as long to compile, there will be fewer sword fights:
http://xkcd.com/303/

Like

• Thanks for the idea about precompiled headers – we’ll check out this tool.

Liked by 1 person

2. Patrick N.

I inherited a solution that has several stdafx.h in various projects so depending what project you’re currently in that you reference a different stdafx.h. This drives me nut because I want to import msxml by issuing the statement “#import msxml…” in the top project “stdafx.h” but it’s not being recognized in the project that uses xml since it’s referencing a totally different stdafx.h. Is there a way we can force all projects to use only one common stdafx.h>

Like

• In fact, all this ‘magic’ with the precompiled headers occurs at the level of translation units with the help of the combination of flags /Yu”path\to\stdafx.h” and /Fp”path\to\pch_file.pch”. You can generate the precompiled header in one of the projects in the solution using the combination of flags /Yc”path\to\stdafx.h” and /Fp”path\to\pch_file.pch” (but you should remember that this project must be compiled the first). Then reuse it in all other projects using flags /Yu”path\to\stdafx.h” and /Fp”path\to\pch_file.pch”.

Like

3. Mr.P

Thanks for your great explanation. Stil it does not solve the problem I’m having currently. I was using precompiled headers for many years in VS2010 but had to upgrade to VS2017 (C++ 11, yeah!). Now my precomiled header gets deleted whenever I compile a project that is supposed to use it.
This is bothering me for some time now, Google does not yield any help at all so far. Do you have any ideas? =)

Best,
Mr.P

Like

• In fact, you need to check 2 combinations of flags on your translation units. When working, stdafx.cpp uses a combination of flags /Yc”path\to\stdafx.h” and /Fp”path\to\pch_file.pch”. Each translation unit that enables the precompiled header, must be compiled with combination of flags /Yu”path\to\stdafx.h” and /Fp”path\to\pch_file.pch”. Path in flags must match. Proceeding from this, try to do the following:

1) Set the flag/Yc”path\to\stdafx.h” to the “stdafx.cpp” file by one of the following ways:
-Right click on stdafx.cpp -> Properties -> C/C++ -> Command Line -> write it in the Additional Options box
-Right click stdafx.cpp -> Properties -> C/C++ -> Precompiled Headers -> set “Precompiled Header” in “Create (/Yc)”, write the path to “stdafx.h” in “Precompiled Header File”

2) The flag /Fp”path\to\pch_file.pch” is set. This will generate a precompiled header file. Set it by two ways:
-Right click on stdafx.cpp -> Properties -> C/C++ -> Command Line -> write it in the Additional Options box
-Either right click on stdafx.cpp -> Properties -> C/C++ -> Precompiled Headers -> in “Precompiled Header Output File” specify the path where to save the precompiled header

3) For each translation unit that connects the preprocessed file, set the flag /Yu”path\to\stdafx.h” and /Fp”path\to\pch_file.pch”. Do similarly to the steps 1 and 2.

Like

4. It is better to use \$(ProjectDir)StdAfx.h;%(ForcedIncludeFiles)
This allows to compile file in other folder without problems.

Like

5. Patrick

Thank you so much for this! I both solved my issue and understand the use of pre-compiled headers 🙂

Like

6. Donatas

I have annoying situation with StdAfx.h
If my project are like this
Project/
StdAfx.h
StdAfx.cpp
run.cpp

folder/
second.cpp

If I add #include “StdAfx.h” in all cpp files. second.cpp says it can’t find StdAfx.h file and here are bunch of identifier xxx is undefined. But project compiles. If I change #include “../StdAfx.h” all classes and functions are recognized. But I can’t compile project.

fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add ‘#include “stdafx.h”‘ to your source?

So, if I include right path to stdafx.h file, I can’t compile project. If I include wrong path to stdafx.h, project compiles, but I get bunch of identifier xxx is undefined. It is very, very annoying.

Like

This site uses Akismet to reduce spam. Learn how your comment data is processed.