1

In the Visual Studio 2015 watch window, pointers can be watched as array by adding a comma and the array length, e.g. d,10 will display 10 elements for a double * d.

Is it possible to create a Natvis Type Entry which does this based on the number of indirections, ie. for d, d* and d** in a different way? Usually those are even members of a type, e.g. struct s { double* d }, but i want to avoid having to write custom visualizers for all those types.

The question is tagged for VS2015 but solutions for vs2017 or vs2019 are welcome if there are any.

Edit1: Here's a simple example of what i'm looking for:

struct S
{
    double* v3;  
    double** m3;
};
int main()
{
    double* pv3 = new double[3]{ -1,-2,-3 };
    double** ppm3 = new double*[3]{ new double[3]{ 1,2,3 }, new double[3]{ 4,5,6 }, new double[3]{ 7,8,9 } };

    S s;
    s.v3 = pv3;
    s.m3 = ppm3;

    double v3[3] = { -1,-2,-3 };
    double m33[3][3] = { { 1,2,3 }, { 4,5,6 }, { 7,8,9 } };
}
  • pv3 and s.v3 should be visualized like v3 and
  • ppm3 and s.m3 should be visualized like m33

I know that treating every double pointer as a double[3] might not be what everyone would want but in certain codebases like the one i'm working on this is the 99% usecase.

ugly annotated vc watch window snapshot

wonko realtime
  • 545
  • 9
  • 26
  • Can you please give a short and simple code snippet for which you want a visualizer (so giving the variables, their types and how you want it to be displayed)!? – Werner Henze Aug 01 '19 at 07:38

2 Answers2

3

I am sorry, but it looks like you can't achieve easily what you want to.

When adding <Type Name="double*"> or <Type Name="double**"> to Natvis Visual Studio complains

Natvis: NatvisFile.natvis(xx,x): Error: not allowed for primitive type 'double**'

So without a code change you would need to add natvis for all of your relevant structs.

But looking at your codebase I want to point you to the CppCoreGuidelines, especially to these rules:

If your codebase would follow these rules and not do array-to-pointer decay, then the full type info would be available in the debugger.

Another approach might be to encapsulate double in a strong type. Please compare this blog post on Fluent{C++}. But this might only work easily if you do not have a legacy API requiring double* or double**.

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
  • 1
    This is all good advice and i'm working on it, but as you said on the last line, it's indeed a large, 30+ year old codebase and needs time to adapt to the new world. I was just hoping that MS maybe is aware of such struggles since it seems to be a common case in old codebases, and provides some backdoor, even if it would be difficult to be accessed. – wonko realtime Aug 07 '19 at 07:49
1

As you noticed in your example, you have a structure S, so you can create natvis for this type:

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
  <Type Name="S">
    <Expand>
      <Item Name="v3">v3, [3]nag</Item>
      <CustomListItems>
        <Variable Name="i" InitialValue="0"/>
        <Loop>
          <Item Name="m3[{i}]">m3[i],[3]nag</Item>
          <Exec>++i</Exec>
          <If Condition="i&gt;=3">
            <Break/>
          </If> 
        </Loop>
      </CustomListItems>
    </Expand>
  </Type>
</AutoVisualizer>

Result for your example: result

But, as @Werner Henze already answered, you can't create natvis for double

mr NAE
  • 3,144
  • 1
  • 15
  • 35
  • `loop` does not work in `vscode`. Any workaround for that? – user10634362 May 27 '22 at 12:10
  • Are you sure? I worked with VS Code a bit, I checked `%USERPROFILE%\.vscode\extensions\ms-vscode.cpptools-1.9.8-win32-x64\debugAdapters\vsdbg\bin\Visualizers\ATLMFC.natvis` - this file contains Loop as well. – mr NAE May 27 '22 at 13:19
  • I have tried in Linux system and failed. If you have time can you kindly take a look [here](https://stackoverflow.com/questions/72359355/extend-display-range-of-arrayitems-indexlistitems-using-natvis?noredirect=1#comment127858705_72359355). As one of the approaches, I have tried here `loop` but failed. Some other approaches were also unsuccessful. Would be great if you kindly go through my question. – user10634362 May 28 '22 at 03:37
  • 1
    I guess, you use `gdb/lldb` for debugging ("type": "cppdbg"). So, in [this case](https://code.visualstudio.com/docs/cpp/natvis) > a subset of the Natvis framework has been ported to the Visual Studio Code C/C++ extension and the code resides in the MIEngine shared component. As WardenGnaw [wrote](https://github.com/microsoft/MIEngine/issues/1095#issuecomment-764961245) > I believe MIEngine does not support `Loop`. – mr NAE May 30 '22 at 11:04
  • Yes, and for that purpose I could not use `loop` in my [issue](https://stackoverflow.com/questions/72359355/extend-display-range-of-arrayitems-indexlistitems-using-natvis) too. Asked in different platform about the [problem](https://stackoverflow.com/questions/72359355/extend-display-range-of-arrayitems-indexlistitems-using-natvis), unfortunately no response came yet. Also I have seen Documentation, provided `natvis` file (seen in windows OS in vscode installation directory) but my approach are seems to be correct. – user10634362 May 30 '22 at 11:34
  • @touraille, a link to your question would be appropriate – mr NAE Aug 07 '23 at 11:45