Debugger visualizers in Visual Sudio 11 Developer Preview

Visual Studio 11 Developer Preview introduces new style debugger visualizers. The autoexp.dat definition of templates in previous versions of the Visual Studio debugger is being replaced with new style definitions based on XML and stored in defaultvis.natvis file.

Microsoft explains the motivation behind redesigning the native type visualization mechanism is to give better diagnostic reporting (visualizer expressions can be now evaluated and displayed in the output window to help debugging .natvis file), provide XSD schema defining type definition, support of multiple files for type definition: system-wide in %ProgramFiles%\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\defaultvis.natvis and user-defined in %USERPROFILE%\My Documents\Visual Studio Dev11\Visualizers\xxx.natvis.

It sounds really good and has a great usability potential for programmers who uses C++ generative programming capabilities, defines complex C++ types, heavily uses C++ Standard Library and Boost C++ Libraries.

Here is example of new style visualizer defined in XML copied from the defaultvis.natvis:

  <!--std::unique_ptr from <memory>-->
  <Type Name="std::unique_ptr<*>">
    <DisplayString Condition="_Myptr == 0">empty</DisplayString>
    <DisplayString>unique_ptr {*_Myptr}</DisplayString>
    <Expand>
      <Item Name="[ptr]" Condition="_Myptr != 0">_Myptr</Item>
    </Expand>
  </Type>

For most types from C++ Standard Library and Windows SDK, the new visualizers work very well. However, the currently available Visual Studio 11 Developer Preview (Version 11.0.40825.2 PREREL) is shipped with incorrect definitions in the defaultvis.natvis. The C++TR1 definitions introduced in Visual Studio 2008 are only forwarded (aliased) from std:tr1:: to std:: in Visual Studio 2010. In Visual Studio 11, they have completely moved from std::tr1:: to std:: to align with C++11 standard. But, the new visualizers in defaultvis.natvis define templates are still referring to the C++11 types in std::tr1:: namespace.

This prevents the correct visualization for types like std::shared_ptr:

vs11-visualizers-broken-2

There is an easy workaround possible:

  1. Make private copy of defaultvis.natvis in %USERPROFILE%\My Documents\Visual Studio Dev11\Visualizers\xxx.natvis where xxx is your preferred name.
  2. Open xxx.natvis in a text editor.
  3. Find std::tr1:: and replace with std::.
  4. Save the changes and relaunch the Visual Studio 11.
  5. You should see objects of the C++11 types correctly visualized.

vs11-visualizers-fixed-3

I have reported this issue to Microsoft Connect in Incorrect Type Name references in defaultvis.natvis visualizers for standard library ticket.

Traits of void resolved

It looks like I’ve got clarified status of the traits of void type. I posted my question to libstdc++ where Paolo Carlini kindly provided me what the bits I have been missing. Now, all the puzzles are in place:

[n1836], the specifications for the TR1 features mandates true for is_pod<void>, etc. Arguably this is a defect, which has been fixed in the ongoing work for the next standard, so-called C++0x.

The TR1 document in section 4.9 states:

8 It is unspecified under what circumstances, if any, is_pod::value evaluates to true, except that, for all types T:

is_pod<T>::value >=
   (is_scalar<T>::value || is_void<T>::value);

Given that, the bug report ID:458570 I submitted to Visual C++ 9.0 and it’s TR1 implementation on Microsoft Connect stays valid and according to what Stephan T. Lavavej confirmed in comments to my report, it’s been fixed in Visual C++ 10.0.

Paolo also added a note particularly important to programmers relying on C++ implementation by GCC compiler and libstdc++ library:

In general, we consider TR1 essentially frozen at this time and minimally maintained, consider that it was just an interim Technical Report

Here are references that are fundamental for the matter:

  • n1836 – Draft Technical Report on C++ Library Extensions
  • n2960 – Working Draft, Standard for Programming Language C++
  • Implementation of is_pod<T> and the rest of type traits by Boost.TypeTraits library.

Mission accomplished ;-)

Traits of void

Long time ago, I reported bug to Visual C++ 9.0 (Visual Studio 2008 SP1) complaining that has_trivial_destructor applied to void returns true (ID:458570). I also discussed it with folks on comp.std.c++ where, among quite different voices, Pete Becker writes:

[tr.meta.req]/8 in TR1 requires is_pod::value to be 1. n2857 is not a standard, and implementations of previous standards are not wrong for not doing what isn’t yet required of them.

and later concludes:

Under the current standard, using the name std::is_pod requires a diagnostic. So if you want to be literal, both compilers are “wrong”. Nevertheless, neither is really “wrong”, they just implement different non-standard versions of is_pod.

So, Visual C++ might actually not be wrong. Fair enough.

Today, I got back to this issue for a while a little extending my test program to use the type traits from both, TR1 and C++0x:

#include <iostream>
#include <tr1/type_traits>
int main()
{
using std::cout; using std::endl;
cout << std::tr1::is_pod<void>::value << endl;
cout << std::tr1::has_trivial_destructor<void>::value << endl;
cout << std::is_pod<void>::value << endl;
cout << std::has_trivial_destructor<void>::value << endl;
}

and compiled it with GCC 4.4.1:

$ g++ -Wall -pedantic -std=c++0x void.cpp
$ ./a.out
1
1
0
0

Now, my confusion has been raised to the power of 2. This is clearly a Polnische Wirtschaft or Czech movie or Turkish sermon

…let’s try to ask libstdc++ folks.