What's New in Visual C++ 2005 IntelliSense?


Li Shao
Microsoft Corporation

January 2006

Summary: Learn how Visual C++ 2005 makes significant improvements to IntelliSense support, including the elimination of prebuilt NCB files, dynamic parsing, macro-based parsing, template specialization support, C++/CLI language support, and much more. (9 printed pages)


Eliminating prebuilt.ncb File
Dynamic Parsing
Macro-based Parsing
Template Specialization Support
C++/CLI Language (New Syntax) Support
IntelliSense Support for Makefile Projects
XML Doc Comments Support
Unicode Support
Better Error Diagnostics

IntelliSense is one of the most popular productivity tools in the Visual Studio editor. We first added support for IntelliSense in Visual C++ 6. We then made incremental improvements in Visual Studio .NET and Visual Studio 2003. Based on customer feedback, we decided to make extensive changes in Visual Studio 2005 in order to satisfy today's software development requirements. Following is a summary of the new features and our improvements.

Eliminating prebuilt.ncb File

The IDE stores IntelliSense information in a database file named <solution_name>.ncb. This file exists per solution and is populated when a solution is first loaded and repopulated on source changes. The work of populating this database is done by a special compiler, the Front End Auto-Completion engine (feacp.dll). Before Visual Studio 2005, there was another type of NCB store named "prebuilt.ncb" that shipped with the product, which was vital to provide complete IntelliSense information. This NCB contained prepopulated symbols from system headers such as ATL, MFC, CRT, and Win32. The IntelliSense engine would then query both the solution NCB as well as the prebuilt.ncb to get complete IntelliSense information. One problem with this design is that IntelliSense displayed many irrelevant symbols. For example, when working on an MFC application, users will also get symbols from ATL headers. In Visual Studio 2005, we re-engineered the process to dynamically parse these system header files. Thus, we have eliminated the need for the prebuilt.ncb. All symbols are stored in the solution NCB store and they are specific to the header files included in a project and specific to the libraries on a machine. This enables IntelliSense to be platform-specific. For example, developers on Device platforms will get IntelliSense information specific to WinCE libraries. It also makes it possible for developers to get IntelliSense when using external libraries. Another advantage we have gained by eliminating the prebuilt.ncb is that we freed some bits in the NCB that indicated whether it was a prebuilt.ncb. We used these additional bits to increase our IntelliSense symbol limit from 16,000 files per solution or 64,000 symbols per solution to 64,000 files per solution. This significantly improved IntelliSense scalability.

Dynamic Parsing

In Visual C++ 6 and Visual Studio .NET, any non-system files must be included in the project/solution in order to get complete IntelliSense. For example, if a project containing a.cpp includes a.h, it is not enough to have a.cpp in the project. The header a.h must be added to the project as well. In Visual Studio .NET, we made an improvement such that #included headers are parsed, which solved this problem. However, there are some limitations to that implementation. For example, any headers that are #included once would get parsed into the NCB store and stay there even if they are no longer included. This can leave invalid symbols in the NCB and cause NCB corruption, which leads to incorrect or dead IntelliSense. Also, any headers that are included through the /FI compiler switch are not parsed. However, in Visual Studio 2005, we improved the dynamic parsing mechanism. Any #include/#import/#using files or those included through /FI/FU are parsed and the symbols from these files are cleared once they are not referenced any more. This leads to a cleaner NCB store and a more reliable IntelliSense experience.

Macro-based Parsing

Before Visual Studio 2005, IntelliSense ignored the preprocessor macro state. In Visual Studio 2005, we introduced macro-based parsing. Essentially, only the source code that is in the active macro state gets parsed. Symbols that are in an inactive block are grayed out and do not appear in IntelliSense. For example, with the following piece of code, when UNICODE is defined, SetWindowTextW is active while SetWindowTextA is grayed out and has no IntelliSense (see Figure 1). If the user undefined UNICODE, SetWindowTextW will be grayed and SetWindowTextA will become active.


Figure 1. Macro-based parsing

One limitation we have with macro-based parsing is that we do not handle the case where a header file is included multiple times with different macro states.

Template Specialization Support

In Visual Studio .NET, the Visual C++ compiler improved its support for template specialization (explicit and partial). IntelliSense, however, did not provide much support for explicit or partial template specialization in Visual Studio .NET. We have improved IntelliSense in Visual Studio 2005 to support these language features. In the sample code below, for example, prior to Visual Studio 2005, the user could not get the correct member list for explicit or template specialization, whereas in Visual Studio 2005 IntelliSense shows the correct members (see Figure 2).


Figure 2: Compare explicit and partial template specialization IntelliSense support in Visual C++ 2005 (A) and Visual Studio .NET (B)

C++/CLI Language (New Syntax) Support

In Visual Studio 2005, we have introduced a new language to allow C++ developers easy access to the common language runtime and the .NET Framework: C++/CLI ("New Syntax" hereafter). This language is an improvement over the managed extensions for C++ ("Old Syntax" hereafter) we have shipped in Visual C++ .NET and Visual C++ .NET 2003. Along with the compiler support, we have implemented IntelliSense support for this language and CLR 2.0 features such as generics. This includes support for ref class/struct, events, properties, index properties, generics, CLR enum, etc. Unfortunately, we do not yet fully support nested generics. For detailed information about this language, please take a look at the C++/CLI Language Specification.

To make our product fully compatible with the existing languages, /clr (New Syntax) and /clr:oldSyntax (Old Syntax) compiler switches were introduced. You can also set these switches through the project properties dialog (Figure 3). You need to select the corresponding settings to make IntelliSense work correctly for applications written in New Syntax or Old Syntax.


Figure 3. CLR switches

Although we provide IntelliSense for both syntaxes, we do not support the scenario where you have New and Old Syntax sources in the same solution. This limitation stems from the fact that symbols from the .NET library can only be parsed in one syntax. A workaround is to port all the sources to New Syntax or separate the sources with different syntax into different solutions.

IntelliSense Support for Makefile Projects

One of the biggest improvements we have made in Visual Studio 2005 is the IntelliSense support for makefile projects. Before Visual Studio 2005, users had little control over IntelliSense support for makefile projects. In Visual Studio 2005, we provide the "IntelliSense" section in the property pages for a makefile project (Figure 4). Here the user can set "Preprocessor Definitions", "Include Search Path", "Forced Includes" (/FI), "Assembly Search Path", and "Forced Using Assemblies" (/FU) for their makefile projects—similar to a traditional Visual C++ project. We have also added complete IntelliSense support for the CLR. The user can set the "Common Language Runtime Support" option to "/clr" if the code is written in New Syntax or "/clr:oldSyntax" if the code is written in Old Syntax.


Figure 4. IntelliSense support for makefile projects

In Visual Studio 2005 there is a new wizard that enables the user to create a makefile project from existing source files. This wizard can be invoked through the File.New Project From Existing Code menu. In one of the wizard pages, you can also specify your IntelliSense options (Figure 5).


Figure 5: Project from existing source code

A useful tip for getting proper IntelliSense support in makefile projects is to set options such as Include Search Path and Preprocessor Definitions correctly so that our IntelliSense engine can find the files it needs to parse as well as parse them in the correct macro state.

XML Doc Comments Support

XML Doc comments are a new way for developers to annotate their code. This feature was first implemented in C#. Users can comment code elements (classes and functions, for example) in a special triple-slash format and these comments will become available when other developers reference these code constructs. In Visual Studio 2005, we have implemented XML Doc Comment support for code written in New Syntax. Here is an example of how to use the XML Doc Comments feature in C++.

First, create a CLR class library project. In the .h file, type in this XML Doc Comment for Class1 (Figure 6):


Figure 6. C++ XML Doc Comments

Then go to the project properties page, expand the Configuration Properties/C/C++ node, select Output Files, and in the right pane change Generate XML Documentation Files to Yes and save. Another option is to throw the /doc switch at the command line. After building the application, you will see that an .xml file is generated along with the dll. When you reference this dll in your application, you will see the XML comment for Class1. One trouble-shooting tip here is to always make sure the XML file is in the same directory as the dll.

There are some limitations for C++ XML Doc Comments in Visual Studio 2005. One is that C++ XML Doc Comments are not available for native development. The other limitation is that C++ XML Doc Comments are available only for symbols from other assemblies that are written in C++ New Syntax, C#, or Visual Basic and referenced via #using the /FU command-line switch, or a project-to-project reference. No XML Doc Comments are available for symbols defined in the current project. Also, there is no auto-completion for XML Doc tags like there is in C#.

Unicode Support

One of the biggest work items for Visual C++ in Visual Studio 2005 is Unicode support. In Visual C++ 6 and Visual C++ .NET our compiler/IDE had no Unicode support. In Visual C++ .NET 2003, the compiler supported Unicode comments and string literals. In Visual Studio 2005, our compiler and IDE support Unicode fully, which means you should be able to use Unicode project/file names and Unicode identifiers for your application. We have also fully implemented the IntelliSense support for Unicode (Figure 7). This will improve the design-time experience for many international customers.


Figure 7: IntelliSense Unicode support

Better Error Diagnostics

We often hear that it is very hard to diagnose IntelliSense failures or report IntelliSense issues. Instead, when IntelliSense did not work, users would delete the NCB file and reload the project/solution. In Visual Studio 2005, along with improving the stability of IntelliSense, we have improved our troubleshooting ability for IntelliSense. In general, it takes some time to build the NCB when first loading a project. In previous versions, users had no indication that IntelliSense was updating, consuming CPU cycles, and disabling some IntelliSense features. In Visual Studio 2005, we output the "Updating IntelliSense. . . " message on the status bar when IntelliSense is updating and also display a progress bar. We also created additional documents for troubleshooting IntelliSense failures: Troubleshooting IntelliSense in C++ Projects, which we point users to when IntelliSense fails. There is also a mechanism in place that can help PSS to troubleshoot IntelliSense failures. We encourage users to call product support when IntelliSense does not behave as expected.

These are major improvements for IntelliSense in Visual Studio 2005. We have also done a lot of work to improve performance and minimize UI locking. Browsing through the source code has also become much easier with the new features such as live browsing, caller/callee graphs, code definition window and go to definition on locals, etc. With these improvements, C++ developers should enjoy a much better editing experience.


I would like to thank Boris Jabes, Ameya Limaye, Dave Waggoner, and Alvin Chardon for extensively reviewing this documentation. I would also like to mention the Visual C++ IntelliSense team, which I am proud to be part of: Dave Waggoner, Ameya Limaye, Tanveer Gani, Shankar Vaidyanathan, Cameron Buschardt, Andras Tantos, Rocky Downs, Tarek Madkour, Boris Jabes, Alvin Chardon, and many others who have contributed to this feature.

© Microsoft Corporation. All rights reserved.