8

Yesterday I discovered MSVC's "Natvis" tool, which allows you to tweak the debugger to present your types in an intelligent way. I quickly set about prettifying my math library.

Here's how my 3*3 matrix class looks (uninitialized data):

matrix 3x3

Gorgeous, right? My afternoon had no regrets.

However, now we get to a slightly more complicated case:

matrix 4x4

As you can see, the numbers do not align. I've figured out a way nasty crock to get the negative numbers to align with the positive numbers, but my method has no way of approaching this (here's my basic outline):

<Type ...>
    <DisplayString>...</DisplayString>
    <Expand ...>
        <Synthetic ...>
            <DisplayString ...>...</DisplayString>
        </Synthetic>
        ...
    </Expand>
</Type>

What's happening is that the number of digits being printed varies from number to number.

Therefore my question: Can I configure Natvis to print a well-defined number of digits for debugging? Alternately, perhaps you have a clever workaround?


P.S.: I will be happy to upload the Python script that generates the ".natvis" file for y'all to play with for your own types, if I get this working.

geometrian
  • 14,775
  • 10
  • 56
  • 132

2 Answers2

4

I ran into the same issue today. After some digging you can do a simpler local solution by just adding the 'g' format specifier:

<Type Name="Rect">
    <DisplayString>Min({myMin.x,g},{myMin.y,g}) Max({myMax.x,g},{myMax.y,g}) Size({myMax.x-myMin.x,g},{myMax.y-myMin.y,g})</DisplayString>
    <Expand>
        <Item Name="[Width]">myMax.x-myMin.x,g</Item>
        <Item Name="[Height]">myMax.y-myMin.y,g</Item>
    </Expand>
</Type>

This results in:

enter image description here

Roy Scheffers
  • 3,832
  • 11
  • 31
  • 36
  • I think perhaps you misunderstand my question. The problem is that the representations have _unpredictable_ lengths (even if they're all decimal), causing lines above each other to not be aligned. – geometrian Aug 29 '18 at 21:29
  • Wasn't answering the question but sooo helpful to me. Take my + – jaba Sep 27 '18 at 16:00
3

In case you are still interested: A nasty workaround is to compute each single digit after the point in natvis and provide a helper type that you can cast your POD data type to:

First you introduce a simple struct to your source code that just holds float or double member in your code. This enables you to cast a float value to NATVIS_FLOAT and access the number.

struct NATVIS_FLOAT { float f;}

Now you can create a visualizer for the NATVIS_FLOAT type, where you define each digit after the precision point that you want to display, e.g. 4:

<Type Name="NATVIS_FLOAT">
   <DisplayString>{(int)f}.{((int)(f*10))%10}{((int)(f*100))%10}{((int)(f*1000))%10}{((int)(f*10000))%10}</DisplayString>
</Type>

Finally you can cast your float members of the matrix to NATVIS_FLOAT. If your matrix has a member float m[9] you can visualize one entry like

{(NATVIS_FLOAT*)&m[2],na}
ta55e
  • 194
  • 8
  • Have a +1 for even answering. I had tried something like this, but I couldn't figure out how to get a constant number of digits to display. The problem is that, while you can specify the digits after the decimal point, you can't specify them before. So e.g. this breaks with the sequence { 0.123, 1.123, 10.123, 100.123, etc. }. – geometrian Feb 20 '16 at 09:31
  • Of course you could use the same technique to display leading zeros, admittedly looking a bit ugly. – ta55e Mar 17 '16 at 10:54