What is "stdafx.h" used for in Visual Studio?
Asked Answered
D

5

566

A file named stdafx.h is automatically generated when I start a project in Visual Studio 2010. I need to make a cross-platform C++ library, so I don't/can't use this header file.

What is stdafx.h used for? Is it OK that I just remove this header file?

Dickie answered 18/1, 2011 at 16:0 Comment(3)
If I get compile error related to stdafx.h, I generally set the settings to do not create or use this file..Azeotrope
Article: StdAfx.h for Novices - viva64.com/en/b/0265Rothberg
You can use the header file just fine on other platforms, to them is just a normal header file. It just offers no performance benefit there.Rusticate
B
928

All C++ compilers have one serious performance problem to deal with. Compiling C++ code is a long, slow process.

Compiling headers included on top of C++ files is a very long, slow process. Compiling the huge header structures that form part of Windows API and other large API libraries is a very, very long, slow process. To have to do it over, and over, and over for every single Cpp source file is a death knell.

This is not unique to Windows but an old problem faced by all compilers that have to compile against a large API like Windows.

The Microsoft compiler can ameliorate this problem with a simple trick called precompiled headers. The trick is pretty slick: although every CPP file can potentially and legally give a sligthly different meaning to the chain of header files included on top of each Cpp file (by things like having different macros #define'd in advance of the includes, or by including the headers in different order), that is most often not the case. Most of the time, we have dozens or hundreds of included files, but they all are intended to have the same meaning for all the Cpp files being compiled in your application.

The compiler can make huge time savings if it doesn't have to start to compile every Cpp file plus its dozens of includes literally from scratch every time.

The trick consists of designating a special header file as the starting point of all compilation chains, the so called 'precompiled header' file, which is commonly a file named stdafx.h simply for historical reasons.

Simply list all your big huge headers for your APIs in your stdafx.h file, in the appropriate order, and then start each of your CPP files at the very top with an #include "stdafx.h", before any meaningful content (just about the only thing allowed before is comments).

Under those conditions, instead of starting from scratch, the compiler starts compiling from the already saved results of compiling everything in stdafx.h.

I don't believe that this trick is unique to Microsoft compilers, nor do I think it was an original development.

For Microsoft compilers, the setting that controls the use of precompiled headers is controlled by a command line argument to the compiler: /Yu "stdafx.h". As you can imagine, the use of the stdafx.h file name is simply a convention; you can change the name if you so wish.

In Visual Studio 2010, this setting is controlled from the GUI via Right-clicking on a CPP Project, selecting 'Properties' and navigating to "Configuration Properties\C/C++\Precompiled Headers". For other versions of Visual Studio, the location in the GUI will be different.

Note that if you disable precompiled headers (or run your project through a tool that doesn't support them), it doesn't make your program illegal; it simply means that your tool will compile everything from scratch every time.

If you are creating a library with no Windows dependencies, you can easily comment out or remove #includes from the stdafx.h file. There is no need to remove the file per se, but clearly you may do so as well, by disabling the precompile header setting above.

Burnejones answered 18/1, 2011 at 17:7 Comment(22)
Even if you used just for files from std namespace you get a speed benefitMarathi
omg ,very nice answer indeed.i was looking for standard compliant c compiler. it turns out that i can disable micro$oft extensions from project properties , change the compiler from "auto" to "c" and your are pretty much having "standard" compiler and IDE.Klaxon
So to clarify, I can just remove the line?Drops
@Rishi: by 'line', do you mean #include "stdafx.h"? Sure, but that's just a standard #include. The "MS extension" part is just a compiler performance optimization; it doesn't change the semantics of having a header file that happens to be called "stdafx.h". Note that if you remove the include and your code depend on anything that was included via stdafx.h, you are going to have to include it directly.Burnejones
So there would be files referenced in "stdafx.h", that I would have to include directly instead?Drops
@Rishi, yes, usually there are include files listed inside. That's the whole point. Whether your program needs those includes or not depends on the program. If you are writing portable program, you probably don't need "window.h".Burnejones
Oh, i don't understand it. I thought headers don't compile. There are just prototypes and declarations, no code, so nothing to compile. So how it this possible?Banquette
@Youda008, not quite true. Before compiling a code file, the contents of headers are simply and literally "pasted" on the spot where you #include them in the source file (done by the same 'preprocessor' step that evaluates macros). The resulting total file is then passed to the actual compiler, which never sees a header file as a separate entity. You only put declarations on header file because that's what works well on a header file - it's a conventional rule. Try it! Create a header file with a whole program, then create a source file that only has an #include for it. It compiles fine.Burnejones
Ye, but if you include header file with code into more cpp files, you will get redefinition error. So who would write a code in header files?Banquette
@Youda008, of course, just like if you typed the code twice. But I think I now understand your question - let me try again: it's true that you don't usually "emit code" from contents of a header file, but a) the compiler doesn't know that until it processes the header, and b) compiling C++ is a lot more complex than just translating formulas to machine code (e.g. templates). Even if no code is emitted, the compiler still needs to process the header and create an internal representation for it, because it alters how it compiles the source file. That's very expensive for complex headers.Burnejones
Historical curiosity. The name of stdafx.h dates from around 1992, when MFC was called 'Application Framework Extensions' before its release. Visual Studio 2015 still defaults to the name ..Normative
(In response to a now-deleted comment: "so, the same as #pragma once?"): No. Pre-compiled headers and #pragma once are orthogonal concepts. Pre-compiled header is an optional compilation performance optimization that makes zero changes to the semantics of the source code. #pragma once changes the semantics of an include file so that it can be inserted multiple times in a compilation unit and it will only take effect at the first insertion point. No relation.Burnejones
A nice idea however a way to optimise the compilation should be just that. If there is no "directive" in a cpp file that should not be "fatal". And there are better ways to do it without enforcing some stdafx header. Any header that has different meanings to different compilation units in theory would break the One Definition Rule. The only preprocessor that might apply in one case and not another should be the include guard.Sialkot
@EuroMicelli So are all header files that are included in stdafx.h compiled separately; and whenever a .cpp file includes it , the compiler simply links the already compiled output with this file?Does the pre- processor paste the code of all the header files at the beginning of .cpp file?If yes then how does it save time on compilation, as the included code will have to be compiled again..Phenosafranine
@KaranJoisher: it's not "pasting" at the source level; that would be what happens without precompiled headers. It's not "compiled output to be linked" either, because what is carried forward from stdafx.h is not a compilation unit, but intermediate compiler internal state that affect how the rest of each CPP file will be parsed. You can think about it as a "saved snapshot" of the compiler memory state at the beginning of the compilation process, which gets saved away and then cloned for each CPP file. Note however that the actual mechanics are not documented.Burnejones
For GCC read info gcc and the node Precompiled Headers which will inform you about building them, including them, and how to build and use separate debug and release build versions in a directory. Or see gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.htmlHorsewoman
@EuroMicelli, wouldn't this make compilation slower than the gcc/clang versions where you can just -include specific_precompiled_header.h for each object recompilation. ie. Where you don't include precompiled headers that you don't use? It seems that doing #include "stdagx.h" at the top of all cpp files would process all precompiled headers for each object file, even though many of them wouldn't use them all, perhaps many of them wouldn't use any. Is that right?Thrasher
@Thrasher sure, maybe. There is more than one valid approach. Whether or not it’s faster that way I don’t know; measure your scenario to find out. For example, for full rebuilds a single shared PCH may be faster because every header in the PCH is (pre)processed just once for the whole build, while using per-compilation unit PCHs might cause the same common header(s) to be (pre)compiled more than once. And if each compilation unit has its own unique set of headers then the advantage of PCHs evaporates in full builds because there is never a chance to reuse them.Burnejones
@EuroMicelli, That doesn't seem to make much sense to me. Pre-compiling the PCH is only ever done once (so long as you don't change the library). As for whether the bulk stdafx can actually make things slower, yeah - I should test this before I speculate further!Thrasher
@Thrasher it sounds like your build process might be different from mine. To me a precompiled header (the output from the precompilation, not the .h header file itself) is an intermediate build artifact, not a source file. They are reused for “plain” or “incremental builds”, but get recreated from scratch during a full rebuild (a “full rebuild” being the same as a “clean” + “build”). On a build server, the result of a PCH is discarded after a build same as with, say, OBJ files. If you never do a full rebuild then the dynamics are different and the comments don’t apply.Burnejones
Are header files compiled? I thought only cpp files get compiled and header files are 'included' in cpp files.Entasis
@ZoomIn, yes sure. Formally the stdafx.h file is also included in a stdafx.cpp file and the compiler runs against the .cpp not the header. And it has to be that way because the compiler needs to know somehow if the header should be read as C or C++ code. But for PCH to work the .cpp cannot contain anything other than the one #include and comments. Internally, the compiler takes the compiler state at the end of that compilation, and uses it as the initial compilation state for the other .cpp files.Burnejones
M
55

It's a "precompiled header file" -- any headers you include in stdafx.h are pre-processed to save time during subsequent compilations. You can read more about it here on MSDN.

If you're building a cross-platform application, check "Empty project" when creating your project and Visual Studio won't put any files at all in your project.

Magneto answered 18/1, 2011 at 16:3 Comment(2)
There's nothing in this file that wouldn't work on other platforms. It might slow down the compilation there, if the compiler doesn't support precompiled headers, but it should not break it. It's just a header file that includes other header files.Errolerroll
@detunized: Maybe my answer made it sound otherwise, so thanks for clarifying that part.Magneto
B
5

"Stdafx.h" is a precompiled header.It include file for standard system include files and for project-specific include files that are used frequently but are changed infrequently.which reduces compile time and Unnecessary Processing.

Precompiled Header stdafx.h is basically used in Microsoft Visual Studio to let the compiler know the files that are once compiled and no need to compile it from scratch. You can read more about it

http://www.cplusplus.com/articles/1TUq5Di1/

https://learn.microsoft.com/en-us/cpp/ide/precompiled-header-files?view=vs-2017

Brahear answered 22/12, 2018 at 19:34 Comment(0)
K
3

Defination: "Stdafx.h" is a precompiled header.

  • Precompiled means once compiled no need to compile again.
  • stdafx.h is basically used in Microsoft Visual Studio to let the compiler know that the files are once compiled and no need to compile it from scratch.

For Example: If you are including the below windows header files.

Code:

#include <windows.h>
#include <string.h>

int main()
{
 //your code
return 0;
}
  • The compiler would always compile these header files from scratch.
  • But if you include #include "stdafx.h" before these headers then the compiler will find the compiled header files from stdafx.h and does not compile it from scratch.
  • For the very first time the compiler compiles as normal from scratch.

Code:

#include "stdafx.h"
#include <windows.h>
#include <string.h>

int main()
{
//your code
 return 0;
}

Advantages:

  • Reduces compile time.
  • Reduces Unnecessary Processing.

Source: http://www.cplusplus.com/articles/1TUq5Di1/

Knecht answered 27/6, 2021 at 9:31 Comment(0)
T
-14

I just ran into this myself since I'm trying to create myself a bare bones framework but started out by creating a new Win32 Program option in Visual Studio 2017. "stdafx.h" is unnecessary and should be removed. Then you can remove the stupid "stdafx.h" and "stdafx.cpp" that is in your Solution Explorer as well as the files from your project. In it's place, you'll need to put

#include <Windows.h>

instead.

Triable answered 4/5, 2017 at 19:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.