Hello, this is Andy Rich from the Visual C++ front-end team. Today, I’ll be discussing the use of precompiled header files (aka PCH files) in our new intellisense architecture.
Back in May, Boris briefly mentioned an intellisense optimization based on precompiled header technology. This post will elaborate on that comment by providing a glimpse into how Intellisense PCH files (or iPCH files) work. We’ve all become accustomed to precompiled headers improving build throughput, and now in Visual Studio 2010, we use the same technology to improve intellisense performance in the IDE.
The VC++ 2010 intellisense engine mimics the command-line compiler by using a translation unit (TU) model to service intellisense requests. A typical translation unit consists of a single source file and the several header files included by that source file (and the headers those headers include, etc.). The intellisense engine exists to provide users with answers to questions, such as what a particular type is, what the exact signature of a function is (and its overloads), or what variables are available in the current scope beginning with a particular substring.
In order for the intellisense compiler to provide this information, the intellisense engine must initially parse the TU like the command-line compiler, recursively parsing all #include files listed at the top of the source file before parsing the rest of the source file. Thanks to C++ scoping rules, we know that we can skip all method bodies except the one you might currently be in, but, other than this optimization, the rest of the translation unit must be parsed to give an accurate answer. We refer to this as the “pre-parse.”
Pre-parses are not always required, as users spend much of their time writing code inside of a local scope. Through careful tracking of user edits, we can say whether or not the user has changed information which requires a new pre-parse. When this happens, we throw away our old pre-parse and start again.
So, even though you aren’t editing header files, they must be continually parsed as part of the pre-parse. As a translation unit grows in size, these parses require progressively more CPU and memory resources, and will lead to a drop in intellisense performance. Parsing is slow, and parsing a lot of information (as in a complex translation unit) can be very slow; 3 seconds is not uncommon, and that is simply too long for an intellisense response.
Luckily, there is an optimization developed for command-line compilers that can also be applied to the intellisense compiler: pre-compiled headers (PCHs). The PCH model presupposes that your translation units mostly share a lot of the same common includes. You inform the compiler of this set of headers, and it builds a pre-compiled header file. On subsequent compilations, instead of re-compiling this set of headers, the compiler loads the PCH file and then proceeds to compile the unique portion of your translation unit.
Unique includesThere are a few caveats to this model. First, the “common” portion of your headers must be the first files compiled in each translation unit, and they must be in the same order in all translation units. Most developers refactor their headers to have a common header file for this purpose; this is what stdafx.h in the Visual C++ project templates is intended for.
In general, if you have PCH set up for use with the build compiler, the intellisense compiler is able to pick up those PCH options and generate a PCH that can be used. Because the intellisense compiler uses a different PCH format from the build compiler, separate PCH files are created for the use of the intellisense compiler. These files are typically stored under your main solution directory, in a subdirectory labeled ‘ipch’. (Future releases may have the command-line and intellisense compilers share these PCHs, but for now, they are separate.)
The intellisense compiler can load these iPCH files to save not only parse time, but memory as well: all translation units that share a common PCH will share the memory for the loaded PCH, further reducing the working set. So, a properly set-up PCH scheme for your solution can make your intellisense requests execute much more rapidly and reduce memory consumption.
Here are some important things to keep in mind when configuring your project for iPCH:
· iPCH and build compiler PCH share the same configuration settings (configurable on a per-project or per-file basis through “Configuration Properties->C/C++->Precompiled Headers”).
· The iPCH should represent the largest set of common headers possible, except for commonly edited headers.
· All translation units should include the common headers in the same order. This may be best configured through a single header file that includes all the other headers, with respective .cpp files including only this “master”header file.
· You can have different iPCH files for different translation units – but only one iPCH file can be used for any given translation unit.
· The intellisense compiler will not create a iPCH file if there are errors in it – open up the ‘error list’ window and look for any intellisense errors; eliminate these errors in order to get PCH working.
· If you feel that an iPCH has somehow become corrupted, you can shut down the IDE and delete the iPCH directory.
About the "Skype" question!
Sounds good. Now please get to work on Intellisense support for C++/CLI so I can start caring about Intellisense again.
"...please get to work on Intellisense support for C++/CLI so I can start caring about Intellisense again."
I have been testing VS2010 BETA2 on a C++ project that uses PCH, and intellisense certainly doesn't work for datatypes included through our StdAfx.h
Btw. VS2010 is not the new VC6, it is just as slow as VS2005 in every aspect when working with large C++ projects.
"... Btw. VS2010 is not the new VC6, it is just as slow as VS2005 in every aspect when working with large C++ projects."
I second that. Why don't you guys get serious about C++ support?
> Now please get to work on Intellisense support for C++/CLI so I can start caring about Intellisense again.
I wouldn't be surprised if MS deprecated C++/CLI in future VS releases. C++/CLI was created to help developers reusing existing C++ code in managed apps, hoping that all managed apps would eventually be completely written in C#/VB.NET.
In my view, making the life difficult for C++/CLI developers is part of the MS strategy (no Intellisense, poor designer support, etc.).
> VS2010 is not the new VC6, it is just as slow as VS2005 in every aspect when working with large C++ projects
I'm sure this will improve. Unlike C++/CLI, native C++ is a priority for MS.
Not having Intellisense is a fitting punishment for people that program in non-standard C++.
My guess is that C++/CLI will soon become obsolete.
> My guess is that C++/CLI will soon become obsolete.
Sad but most likely true.
I also thought VS2010 performance was supposed to be priority.
What happened to "10 is the new 6"? Killed by cool new bling? (yet again)
@Rolf: I'm very interested in trying to figure out why your PCH scenario is not working. If you wouldn't mind helping out, could you e-mail me directly at 'jamie at microsoft dot com' and we can attempt to determine what is going wrong? I also wouldn't mind discussing your scalability issues.
Boris Jabes has previously made comments regarding our reduced C++/CLI support in Dev10 (and what that means for future releases) here: http://blogs.msdn.com/vcblog/archive/2009/05/27/rebuilding-intellisense.aspx#9656003
But in short, we have no plans to deprecate C++/CLI support in the build compiler, and do fully intend to support C++/CLI intellisense in the future.
I have posted some feedback on Connect Live, that is already being looked at by your co-workers.
Though to report issues I experience with large C++ projects, then the most common reply is to create a sample project (don't have the time to create a massive hello world program).
@Rolf : LOL... I have tried to show the problems and I usually get "not reproducible" so I sort of gave upon it.
It is hard to share my company intellectual properties to show a problem on the IDE. I dont have the rights and cannot do so. With big projects VS 2010 behaves very strange. All they have to do is to load a project do some compilations, debugging and some breaks and errors... problems starts to popup. For me VS 2010 is not stable. I have to restart it sometimes or it just crashes and restarts itself. Before it used to report errors back to microsoft and now a days... looks like VS 2010 has fed up uploading crash reports and dont bother to do that anymore :)
10 is not the new 6 and it will never be ( if this is the direction which we are going ) the marketing guys can say any thing, to get something out of nothing.
.net is where the business for microsoft, so it is obviously their choice and they allocate resource and time to develop that rather than the age old C++. It is a no brainer, I feel very bad about it, there hasn't been any remarkable development in Visual C++ since VC 6. Dont say that the parallel libraries are.. it was developed in order to write .net libraries on top of it.
> there hasn't been any remarkable development in Visual C++ since VC 6.
Conformance to the Standard was massively improved between VC6 and VC8, TR1 was added in VC9 SP1, and part of C++0x is being added in VC10.
Stephan T. Lavavej, Visual C++ Libraries Developer
@ Stephan : I agree Stephan, but those are all language enhancements rather than innovations around VC++ related libraries. One thing that comes to my mind is that Direct2D libraries and webservice api. I do really appreciate your efforts on STL and VC++ as a whole. The point I wanted make was that, there were no real effort, atleast that I can see, from microsoft to make life easy for the native developers, unfortunately it remains the same or gone bad from VC6 onwards.