Why isn't include stdafx.h not enough for VisualStudio? - c++

I understand that the purpose of precompiled header is about to speed up compilation process by using object file that was already compiled once and link it to actual project. But what I do not uderstand Is why should I explicitly enforce Visual Studio to use stdafx.h (Project Properities -> C/C++ -> Precompiled Headers -> Precompiled Header)? Why isn't #include "stdafx.h" not enough?

Why isn't #include "stdafx.h" [...] enough?
Because that is just a standard C++ preprocessor directive.* It's no different from #include <string> as far as the compiler is concerned. If you need to have additional semantics attached, you have to tell the compiler about it.
Since there appears to be confusion, how Visual Studio implements precompiled headers, here is a link to documentation: Creating Precompiled Header Files.
* Mind you, there's nothing special about the name "stdafx.h", other than it being the default header name used to generate a PCH.

So called stdafx.h is supposed look as an ordinary header file. There's nothing special about its name. It is not supposed to automatically enable precompiled headers.
The idea is that stdafx.h will be seen as an ordinary header file by any other compiler and/or when you don't what to use precompiler headers in MSVC.
It is you who are supposed to tell the MSVC compiler that you actually want to enable precompiled headers. That's exactly why you have that project setting. And only when you enable precompiled headers, stdafx.h will acquire its special role and will receive special treatment from the compiler. And it is not necessarily stdafx.h. You can assign this special role to any other header by specifying a different name in project settings.
In fact, seeing a reference to AFX in a project that has nothing to do with Microsoft-specific libraries or frameworks would be quite an oddity.

Related

Debug mode throws #include errors that release mode doesn't [duplicate]

This question already has answers here:
What is "stdafx.h" used for in Visual Studio?
(5 answers)
Closed 5 years ago.
What is the purpose of the file stdafx.h and what is meant by precompiled headers?
stdafx.h is a file, generated by
Microsoft Visual Studio IDE wizards,
that describes both standard system
and project specific include files
that are used frequently but hardly
ever change.
Compatible compilers (for example,
Visual C++ 6.0 and newer) will
pre-compile this file to reduce
overall compile times.
Visual C++ will
not compile anything before the
#include "stdafx.h" in the source file, unless the compile option
/Yu'stdafx.h' is unchecked (by
default); it assumes all code in the
source up to and including that line
is already compiled.
http://en.wikipedia.org/wiki/Precompiled_header
To expand on the other excellent answers:
stdafx.h is the file that includes all of the commonly used headers for a single project. This would include all of the Windows definitions, for example. Because this file includes so much stuff, the compiler gets a bit slow when processing it. By precompiling it, the compiler can skip much of the processing and reuse it over and over again; as long as none of the files included by it change, the precompiled result doesn't need to change either.
The name stdafx.h is just a convention. You could easily rename it to something else if you changed all your sources to include the new file instead.
To produce the actual precompiled header file, you need one source file in the project that has special compile flags to produce precompiled output. By convention this file is named stdafx.cpp, and if you inspect the settings for that source file you will see how it is different.
It's typically used for the name of precompiled headers. Although using that exact name is not required, just the default. I explain more about pre-compiled headers on VC++ and g++ here.
You use precompiled headers for faster compilation.
The idea is that you put any header file that will not change, and that you use in several source files inside your precompiled header. Then the compiler will not need to reprocess those headers for each compilation unit.
It's a precompiled header, to reduce compilation times.

Why do we use `#include "stdafx.h"` instead of `#include <stdafx.h>`?

From here, it is said that:
For #include "filename" the preprocessor searches in the same
directory as the file containing the directive. This method is
normally used to include programmer-defined header files.
For #include <filename> the preprocessor searches in an implementation
dependent manner, normally in search directories pre-designated by the
compiler/IDE. This method is normally used to include standard library
header files.
While this wiki link suggests that stdafx.h is an header file pre-designed by visual studio IDE
stdafx.h is a file, generated by Microsoft Visual Studio IDE wizards,
that describes both standard system and project specific include files
that are used frequently but hardly ever change.
Compatible compilers (for example, Visual C++ 6.0 and newer) will
precompile this file to reduce overall compile times. Visual C++ will
not compile anything before the #include "stdafx.h" in the source
file, unless the compile option /Yu'stdafx.h' is unchecked (by
default); it assumes all code in the source up to and including that
line is already compiled.
The AFX in stdafx.h stands for Application Framework eXtensions. AFX
was the original abbreviation for the Microsoft Foundation Classes
(MFC). While the name stdafx.h is used by default, projects may
specify an alternative name.
Then
Why do we use #include "stdafx.h" instead of #include <stdafx.h> ?
A stdafx.h, stdafx.cpp pair is generated by VS from a template. It resides in the same directory the rest of the files end up. You will probably end up altering it specifically for your project. So we use "" instead of <> for exactly the reason that it's in the same directory as your first quote describes.
Because stdafx.h is different for each project. As you quoted, #include "" searches the path of the current project, and this is where stdafx.h is located.
Using #include <stdafx.h> would be a huge mistake, because it would have to be in the library path (where all the standard library headers are located). This would mean that you shouldn't modify it, or that it always stays the same, but it's never the same for different projects.
So even though it is generated by Visual Studio, it is specific to the project, not to all projects.
In general, for a given include file name.h, the syntax #include <name> is reserved for the standard libraries, while #include "name.h" is used for user-defined files. There, 'user' could mean any developer implementing non-standard features, say for a particular compiler package.
Accordingly, the preprocessor searches for the include files following the suitable paths specified by the system settings in place. Note not only the difference between brackets and quotes, but also the different usage of the *.h extension.

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.

stdafx.h cross platform without issues?

Hey i've been following learncpp.com tuts for the last couple days, they say to comment out "#include "stdafx.h" from .cpp files for Code::Blocks.
Is that a must, to remove the include line? What happens if you had hundreds of files and changed from Visual Studio on Win7 to Code::Blocks on Linux or hand it off to someone else with a mac?
stdafx.h is the idiomatic name used for precompiled headers in the Visual Studio ecosystem. In a nutshell, it's a regular header, but the contents of this file will be compiled once and reused for all cpp files in the project.
That is useful since in most projects, a large number of headers (standard library, system header, shared project-wide definitions) are used by virtually all translation units (cpps), so using PCH is a huge performance benefit during compilation
(Actually, PCH is a hack to workaround C++' inefficient compilation and linkage model and it's a shame that we need to maintain it by hand … oups, blasphemy.)
But this also means that - as long as the contents of your stdafx.h are gcc-compatible - compilation with CodeBlocks should still work, but without the immediate performance benefit.
The stdafx.h generated by VS' app wizards doesn't work out of the box on other platforms - it typically includes Windows.h. So to make it work, guard the Windows-specific definitions with appropriate #ifdef/#endif pairs and vice versa for Linux or Mac-specific stuff.
No, that tutorial advice does not make any sense. stdafx.h does not break anything at all. The system of pre-compiled headers in Visual Studio compiler is intentionally designed that way.
If your compiler supports pre-compiled headers (and follows the same pre-compilation approach as Visual Studio), it can use stdafx.h for pre-compiling.
If your compiler does not support pre-compiled headers (or used a different pre-compilation approach), then stdafx.h is interpreted as an ordinary header file, no different from any other header file and processed the same way as any other header file.
It is possible that what is meant by that tutorial is that stdafx.h often includes some Windows-specific headers, not present on other platform. While it is possible, it really has nothing to do with stdafx.h itself at all. Obviously, if you are compiling your program on some other platform you should not attempt to include any Windows headers, regardless of how you are doing it: through stdafx.h or somewhere else.
As far as I'm aware stdafx.h is a Windows-only file (for precompiled headers): Your code will just fail to compile if you don't comment it out.
If you are not actually using a precompiled header (PCH), I advise going into Visual Studio's Options/Preferences->Precompiled Header and turning them off. If you try to remove them and still use Visual Studio, you will get a ton of errors.
The only thing to actually do is to include the path containing the stdafx.h (or precompiled header) in the default include path list. This is needed because the MS compiler actually replaces the #include "stdafx.h" with the precompiled data without really looking for the header.
Other compilers will usually want to pull in the data. But it should rather not be commented out. Usually you'll be able to tune your compiler to also make use of the precompiled header features to boost up compilation. With gcc that would be done with the -pch option. With Code Blocks I could find this wiki. Precompiled headers are not evil, on the contrary they will save you precious time if understood and used adequately.

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.