Inspecting the state of a variable during a debug session is a fundamental activity of producing software. For simple data types such as integers and short strings, the textbox-based display of a variable's value is adequate. In fact, it's been used in debuggers for many years. However, for complex data types that have many internal variables and that have deep and complex relations with other types, the traditional display offered by debug windows like Quick Watch is far from ideal.
Visual C++ 2005 offers a number of improvements in the way data can be examined during a debug session. The first improvement is the DataTip. A DataTip is similar to the QuickWatch window in terms of its functionality, but rather than using a modal window that needs to be manually activated, a DataTip will pop up in the same manner as a ToolTip. To access the DataTip for a variable, simply hover over any line of code where the variable is used when the debugger is in Break mode. A ToolTip-like window will appear, displaying the same top-level debug information that the Watch window would display. As with the Watch window, expansion is possible so that you can examine the data member of a variable. Figure 1 shows an expanded DataTip for a SqlConnection object.
Figure 1. DataTips in Visual Studio.NET 2005
Controlling Variable Display
Looking at the amount of data displayed in Figure 1, it is apparent that although DataTips make it very easy to bring up information about the state of a variable, navigating through the great quantity of information that a complex variable such as a database connection possesses is still time consuming and difficult. To allow the member variables of a type to be organized so that the most relevant items are the most visible to a user, the Visual C++ debugger ships with the ability to customize the display of classes in debug windows. This ability has been present in Visual C++ for many versions, and many developers will be familiar with the use of autoexp.dat and mcee_mc.dat for controlling the display of native and managed types, respectively.
Both these files have expanded considerably going from Visual C++ 2003 to 2005. The file size of autoexp.dat has gone from 6 Kb to 51 Kb and the file size of mcee_mc.dat has gone from 4 Kb to 11 Kb (these figures are based on Beta 2 of Visual C++ 2005). The increase in size represents both an increase in the coverage of the types as well as enhanced syntax that makes the display of types much richer. In mcee_mc.dat, the improved functionality revolves primarily around the display of collections. Settings for the collections that ship with the .NET Framework Library, as well as the STL, are included with this file. For a .NET ArrayList and HashTable, the syntax for the display is as follows:
expr : ($c._items)[$i],
size : $c._size
#if($e.hash_coll == 0)
key: $e.key ,
Figure 2 shows the result of these settings.
Figure 2. ArrayList and Hashtable Variables in the Watch Window
Although the use of these macro-like expressions is not documented, the number of special constants such as #array is fairly limited, and custom settings can be constructed based on existing settings without too much pain. Once Visual C++ 2005 has been released and any bugs relating to using this syntax in custom types have been ironed out, I'll revisit this topic and show how to use these collection visualizers for your own types.
The syntax for autoexp.dat (which is used to control the display of unmanaged types) is similar, but the complexity of unmanaged types and the use of features like unions and nested templates mean that the types described tend to be more complex. As with mcee_mc.dat, the syntax for describing types is currently undocumented, but there is a wealth of examples that span types from the Windows SDK, STL, ATL, and MFC. For most developers who have used STL with Visual C++, trying to figure out the values that a collection holds is very painful. The massively expanded autoexp.dat addresses this problem quite well. Figure 3 shows the debug display of an STL vector in Visual C++ 2003 that contains three elements: 0, 1, and 2. Determining this from the debug display is not possible.
Figure 3. STL Vector Display in Visual C++ 2003
Figure 4 shows the display of the same variable in Visual C++ 2005. The difference in usefulness between the two displays is obvious.
Figure 4. The Same Variable in Visual C++ 2005