Visual Studio C++ lib project
Project is set to use precompiled headers
stdafx.cpp is set to create precompiled header
I have a header file, MyClass.h
If I build, then make a change to MyClass.h that should fail to compile, compile still succeeds.
If I do a rebuild, or if I make a change to a cpp file that includes "MyClass.h", then the compile fails as expected.
Is this expected because I'm using precompiled headers? Is there any way to fix it so a 2nds buid picks up header changes without turning off precompiled headers?
Make sure that the header file you are altering is referenced by your project in Solution Explorer. If this is the case, the full build should trigger when it is changed.
In the project properties, set "Enable Minimal Rebuild" to No
Are you sure that stdafx.cpp includes the header in question?
VisualStudio can often get pretty damn stupid over changes. It can go either way, but usually it goes the way you're running into.
I've had it catch onto changes in a header used by one file, but not the fact that it's used in others. So it compiles the one but not the others. Then I get really weird linker errors.
It could of course still be your own damn fault, but VS is, in fact, notoriously stupid. Sometimes a complete rebuild will fix the issue permanently, until next time. Other times you have somehow hosed the project file and hopefully you can get back to the original (like a source server revert). "Undo" most usually does not undo this kind of fubar.
I've noted this several times not needing to be a header that's in the precompiled header. It seems to be somewhat random but one more common correlation is that the header is full of templates. VS is just plain retarded wrt templates.
Related
I have noticed some odd behaviour in VS2012 while working with some C++ projects. If I put the following line at the top of a header file: (myclass.h)
#include <D3DX11.h>
The compiler will tell me that it can't find the file (even though intellisense suggests it). However, if I put the same line in a different file (myclass.cpp) everything works just fine. I don't understand why it can be found when used in one file, but not the other? What is going on ?
EDIT / NOTE:
This isn't really a DirectX specific issue. That is just what I was working with when I decided to ask. This can happen in other places as well.
In the newer versions of visual studio the include paths are set at project-level. Maybe the project containing the cpp has the proper path set (see the comment from Jesse Good in your question). However that might not be the case for another project in your solution. As soon as you put the include in the header, all other projects including your header will need to know where to find the directX-headers as well.
Beware of intellisense - if you open a header it has to guess what cpp you might include this header from and the displayed info is not always correct. I think in the newer versions it even depends on what other files are opened / project is selected.
The compiler should inform you what cpp actually causes problems when including the header.
I recently switched to Visual Studio 2010 and for Intellisense not to take half a minute to show up when using boost libraries, Microsoft's suggestion seems to use precompiled headers.
Except that I never used them before (except when forced to by Ugly ATL Wizards (TM)), so I searched around to figure out how they work.
Basically, the Big Centralized stdafx.h approach seems plain wrong. I never want to include (even cheaply) a whole bunch of header files in all my sources. Since I don't use windows libraries (I make C++/CLI higher level wrappers, then use .NET for talking to the outside world), I don't have "a whole truckload of non-changing enormous headers". Just boost and standard library headers scattered around.
There is an interesting approach to this problem, but I can't quite figure out how to make this work. It seems that each source file must be compiled twice (please correct me if I'm wrong): once with /Yc and once with /Yu. This adds burden on the developper which must manually tweak the build system.
I was hoping to find some "automatically generate one precompiled header for each source file" trick, or at least some "best practices", but most people seem happy with including the world into stdafx.h.
What are the options available to me to use precompiled headers on a per source file basis ? I don't really care about build times (as long as they don't skyrocket), I just want intellisense to work fast.
For starters, you are reading the article wrong. Every file is NOT compiled twice. The file stdafx.cpp gets compiled once with /Yc (c, for create) before anything else and then every other file in your project gets compiled once with /Yu (u, for use) and imports the result of the previously created saved state from stdafx.cpp.
Secondly, the article is 7 years old and is talking about VC++ 6, so you should start off distrusting it. But even assuming the information in it still applies to VC++ 2008 or 2010, it seems like bad advice. The approach it recommends using /pragma hdrstop is solution looking for a problem. If you have headers that contain things you don't want in every file, then they simply shouldn't go in your pre-compiled header.
Your problem basically seems to be that Intellisense is slow for Boost in VS2010? I don't have a direct solution for this problem, but could Visual Assist X be an option for you? I have used it in various versions of Visual Studio now and with great pleasure. Not a direct solution, but it might work for you.
Precompiled headers aren't too bad if you use them properly.
Don't use them as a replacement for proper and precise #includes, but as a way to speed things up. Achieve this by making the precompiled header do nothing in release builds, only speeding stuff up in debug.
You are wrong, each file is only compiled once. You have one .cpp file that is compiled with /Yc and the rest are compiled with /Yu. The file with /Yc, which is stdafx.cpp by default, contains one line, #include "myMainHeader.h" (changed the name from the default) All other .cpp files must start with #include "myMainHeader.h" When your /Yc file is compiled, the entire internal state of the compiler is saved. That file is loaded when each of your other files is compiled. That is why you must start with including the PCH, so that the /Yu option doesn't change the result of compilation, only the time. Xcode does not make this requirement and will use a PCH regardless of if your .cpp file starts with the right include directive. I have used libraries that relied on this and could not be built without PCH.
I'm a beginner starting to use Microsoft Visual C++ Express 2010 for Windows Programming. I've created a new C++ application using native code, not managed or MFC. I had Visual Studio create for me the basic windows code to create one window with simple menus (chat.cpp). I modified this file and I was able to compile correctly and see my changes take effect.
Now I've added one more source file to the solution (intro.cpp) which I include in my header and call from within chat.cpp. This seems to work just fine, but with one problem. The compiler doesn't seem to be applying my code changes occasionally: I make various edits, recompile, and the "old" code seems to be running. Then, after a while, after I make only a tiny modification, the compiler seems to "catch up" and it runs the new code including all the previous changes I had made.
Is there some kind of cache? Do I need to tell the compiler which files to compile and which ones to just link from object files? Did I make a mistake when I added the file to the solution?
Does intro.cpp have a header file? is that in your solution too?
It's hard for me to imagine that this area of such a mature IDE has a bug here, so I would examine your file list first. Make sure that the Solution Explorer shows all the files you have added and are editing. This is the list that VS uses to determine rebuild is needed.
EDIT: I admit it's not clear to me from your description why it would fail right now. However, typically header files do not include code, it works the other way around (except for class template header files, such as the STL headers). There is some discussion about pros and cons here. The most compelling argument to me in favour of code including headers rather than vice versa is that the header file contains the interface, while the code file contains the implementation.
I would try restructuring your code to a more traditional structure where intro.cpp includes intro.h and any others it needs, and the same with chat.cpp. Then your compilation units are intro.cpp and chat.cpp, and they depend on the associated header files, so provided they are properly listed in the SOlution Explorer, all should work. You can clean up the build dependencies to avoid dups and reduce build time once you have it working as you wish.
In some of my VS 2005 projects, when I change an include file some of the cpp files are not rebuilt, even though they have a simple #include line in them.
Is this a known bug, or something strange about the projects? Is there any information about how VS works out the dependencies and can I view the files for that?
btw I did try some googling but couldn't find anything about this. I probably need the right search term...
I've experienced this problem from time to time, and with other IDEs too, not just VS. It seems thatv their internal dependency tree sometimes gets out of whack with reality. In these cases, I've found deleting pre-compiled headers (this is important) and doing a complete rebuild always solves the problem. Luckily, it doesn't happen often.
To be honest I never faced such a problem using Visual Studio. Your CPP should be rebuild as well if it includes the header. The only reason I can come up with: same include file is taken from 2 different sources.
You can try do debug this at compile time, by enabling the preprocessor to output preprocessed files. Click on the CPP file go to properties and then to C/C++->Preprocessor and select in "Generate Preprocessed File" the item with or without line numbers.
Go to you include file put the pragmas around your newly added definitions like:
#pragma starting_definition_X
...
#pragma ending_definition_X
Now compile everything. There will be a newly created file with the same name as CPP but with extension .I (or .i).
Make a search if your pragmas are there. If not, your include come from another place.
If you use pre-compiled headers, you cpp should rebuild. There is also a pragma once statement in MS VC, which parses the include file only once, but that should still recompiler you cpp-file.
Hope that helps,
Ovanes
Do you have the "Minimal rebuild" option turned on?
Visual studio compares the timestamps on the files. So you might want to check that your system clock is set correctly and also that none of the files has a funny timestamp on it. Look at the include files, the cpp files, the pch files and obj files and make sure all the timestamps look reasonable. In particular, make sure none of them are in the future.
Was the .h files added in the project? If not, then vs maybe unable to find out the dependency.
Thanks for all the answers they have helped point me in the right direction.
I have discovered that deleting the idb file and rebuilding will then allow subsequent modifications of .h files to cause the correct .cpp files to be built. However this causes the entire project to be rebuilt which just brings me back to Neil Butterworth's suggestion of doing a full rebuild. I don't think there is much else I can do about it.
As an aside, looking at the bad and good idb files I can see that the cpp file that was not being built is not in the bad idb, whereas it is in the good idb. The header file that is being changed is mentioned several times in both files.
win_pdbx (download) can extract the idb file and moyix has published some information about the streams in these files.
Stream 4 contains the file paths of the cpp files but I have not been able to determine the format.
As usual, when my brain's messing with something I can't figure out myself, I come to you guys for help :)
This time I've been wondering why stdafx.h works the way it does? To my understanding it does 2 things:
Includes standard headers which we
might (?) use and which are rarely changed
Work as a compiler-bookmark for when
code is no longer precompiled.
Now, these 2 things seems like two very different tasks to me, and I wonder why they didn't do two seperate steps to take care of them? To me it seems reasonable to have a #pragma-command do the bookmarking stuff and to optionally have a header-file a long the lines of windows.h to do the including of often-used headers... Which brings me to my next point: Why are we forced to include often-used headers through stdafx.h? Personally, I'm not aware of any often used headers I use that I'm not already doing my own includes for - but maybe these headers are necessary for .dll generation?
Thx in advance
stdafx.h is ONE way of having Visual studio do precompiled headers. It's a simple to use, easy to automatically generate, approach that works well for smaller apps but can cause problems for larger more complex apps where the fact that it encourages, effectively, the use of a single header file it can cause coupling across components that are otherwise independent. If used just for system headers it tends to be OK, but as a project grows in size and complexity it's tempting to throw other headers in there and then suddenly changing any header file results in the recompilation of everything in the project.
See here: Is there a way to use pre-compiled headers in VC++ without requiring stdafx.h? for details of an alternative approach.
You are not forced to use "stdafx.h". You can check off the Use precompiled headers in project properties (or when creating the project) and you won't need stdafx.h anymore.
The compiler uses it as a clue to be able to precompile most used headers separately in a .pch file to reduce compilation time (don't have to compile it every time).
It keeps the compile time down, as the stuff in it are always compiled first (see details in quote below):
stdafx.h is a file
that describes both standard system
and project specific include files
that are used frequently but hardly
ever changed.
Compatible compilers 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.
It will help reduce long compilations.