I have been using the .NET debug visualizers (and DebuggerDisplay atribute) for a long (long) time and I like the way they make my code easy(ier) to debug. Until recently I was not aware that Visual Studio has a similar capability for C++.
Any C++ dev armed with Visual Studio can use XML files to create debug visualizers, In Visual Studio 2015 there’s no longer a need to to deploy these visualizer on each on each developer machine – just add the new, easy to write visualizer to your project and your team gets to automatically use it via the magic of source control.
Consider the following class:
class Customer
{
int m_id;
string m_firstName;
string m_surname;
int m_age;
Gender m_gender;
string m_emailAddress;
string m_telephoneNumber;
Address m_address;
// ...
};
In order to use a debug visualizer just add a new natvis file - Add new Item and choose the Debugger visualization file (.netvis) template.
And presto - a new debug visualization file would be added to your project.
After a little tinkering I’ve created the following:
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="Customer">
<DisplayString>Name: {m_firstName}</DisplayString>
<Expand>
<Item Name="Id">m_id</Item>
<Item Name="Gender">m_gender</Item>
<Item Name="Age">m_age</Item>
<Item Name="Address">m_address</Item>
</Expand>
</Type>
</AutoVisualizer>
Which was really simple to write:
- To display the customer’s name automatically I’ve added DisplayString with “Name:” and the value in curly brackets.
- Right now I only care about four of the customer’s fields so I’ve added Expends with those fields
And I got the following in my watch window:
Which is nice but not great – I would like to see the customer full name and so I’ve tweaked DisplayString a bit:
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="Customer">
<DisplayString>Name: {m_firstName, sb} {m_surname, sb}</DisplayString>
<Expand>
<Item Name="Id">m_id</Item>
<Item Name="Gender">m_gender</Item>
<Item Name="Age">m_age</Item>
<Item Name="Address">m_address</Item>
</Expand>
</Type>
</AutoVisualizer>
And I did it during a debug session – seeing the results each time I save the natvis file:
I’ve used Format specifier (that’s the “sb”) to remove the quotes and make the name more human readable. In fact I can use another formatter for Gender – en (for Enum).
I would also like to make the customer address visible in the display string. Since Address is a class I’ll first define a visualizer for it (blow the customer visualizer) and update the customer visualizer to use the address as part of the display string:
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="Customer">
<DisplayString>{m_firstName, sb} {m_surname, sb} [{m_address}]</DisplayString>
<Expand>
<Item Name="Id">m_id</Item>
<Item Name="Gender">m_gender, en</Item>
<Item Name="Age">m_age</Item>
<Item Name="Address">m_address</Item>
</Expand>
</Type>
<Type Name="Address">
<DisplayString>{m_streetAddress, sb}, {m_city, sb}, {m_country, sb} Zip:{m_zipCode}</DisplayString>
</Type>
</AutoVisualizer>
This doesn’t seem much – but in order to get similar behavior in .NET I’ve needed to use OzCode – since nested/recursive DebugDisplayAttribute is not supported in .NET.
Conclusion
There are other nifty debug visualizer related features in VS2015 but I find the ease of use and deployment to be the real game changer.
Now when I get to look at big vector of Customers without needed to expend and find what I want:
As simple as that.
Happy coding (Even in C++)…Labels: C++, Debug, Visual Studio 2015