1

I want to make gsl::span to be as debug friendly as std::vector/std::array, in the Visual Studio debugging environment.

Here is what I mean.

Given this code

    struct custom_class
    {
        custom_class(std::vector<int> & foo) : ptr(foo.data()), length(foo.size())
        {}

        int* ptr;
        size_t length;
    };



    void vector_example()
    {
        std::vector<int> vector_foo = { 0,1,3,4,5,6,3,2 };

        std::array<int, 8> array_foo = { 0,1,3,4,5,6,3,2 };

        gsl::span<int> span_foo(vector_foo);

        custom_class custom_class_foo(vector_foo);

        std::cout << "How can I make my class as debug friendly as std::array and std::vector?" << "\n";
    }

The debugger is able to visual std::vector/array like this:

std::array

-       array_foo   { size=8 }  std::array<int,8>
        [0] 0   int
        [1] 1   int
        [2] 3   int
        [3] 4   int
        [4] 5   int
        [5] 6   int
        [6] 3   int
        [7] 2   int
+       [Raw View]  {_Elems=0x000000654696f368 {0, 1, 3, 4, 5, 6, 3, 2} }   std::array<int,8>

std::vector

-       vector_foo  { size=8 }  std::vector<int,std::allocator<int>>
        [capacity]  8   __int64
+       [allocator] allocator   std::_Compressed_pair<std::allocator<int>,std::_Vector_val<std::_Simple_types<int>>,1>
        [0] 0   int
        [1] 1   int
        [2] 3   int
        [3] 4   int
        [4] 5   int
        [5] 6   int
        [6] 3   int
        [7] 2   int
+       [Raw View]  {_Mypair=allocator }    std::vector<int,std::allocator<int>>

But when I look at std::span and my own custom class, I can't look past the first indice in the debugger

Custom Class

-       custom_class_foo    {ptr=0x0000015f50e3c340 {0} length=8 }  `anonymous-namespace'::custom_class
-       ptr 0x0000015f50e3c340 {0}  int *
            0   int
        length  8   unsigned __int64

gsl::span

-       span_foo    {storage_={data_=0x000001f5bb2fdc20 {0} } } gsl::span<int,-1>
-       storage_    {data_=0x000001f5bb2fdc20 {0} } gsl::span<int,-1>::storage_type<gsl::details::extent_type<-1>>
-       gsl::details::extent_type<-1>   {size_=8 }  gsl::details::extent_type<-1>
        size_   8   __int64
-       data_   0x000001f5bb2fdc20 {0}  int *
            0   int
Claudiu Guiman
  • 837
  • 5
  • 18
  • 1
    Visual Studio allows customization of the output: [https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2019#BKMK_Using_Natvis_files](https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2019#BKMK_Using_Natvis_files) – drescherjm Nov 04 '19 at 20:33

1 Answers1

1

Turns out the Guideline Support Library already has native visualization support.

I didn't realize this since I just copied the include folder into my project, instead of properly adding it as a CMake project.

Cmake as of 3.7.x handles including *.natvis files.

I'm going to link to the gsl natvis for the guideline support library since it also provides a really good example for those looking to make their native visualizers.

https://github.com/microsoft/GSL

https://github.com/microsoft/GSL/blob/master/GSL.natvis

https://github.com/microsoft/GSL/blob/master/CMakeLists.txt

Edit:

Just in case those links die I'm going to highlight the important bits. Mainly how to make a native visualization for 'array proxy classes'.

And how to add it to your project in cmake. (In this case GSL's CMakeList handles it for you if you include the project, so you don't have to write this for GSL. But if you have your own custom class this is useful for reference)

GSL.natvis

<?xml version="1.0" encoding="utf-8"?>
<!-- 
    This will make GitHub and some editors recognize this code as XML: 
    vim: syntax=xml
-->
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">

    <!-- other stuff that isn't gsl::span  ... -->

    <!-- These types are from the span header. -->
    <!-- This is for dynamic_extent spans. -->
    <Type Name="gsl::span&lt;*, -1&gt;">
        <DisplayString>{{ extent = {storage_.size_} }}</DisplayString>
        <Expand>
            <ArrayItems>
                <Size>storage_.size_</Size>
                <ValuePointer>storage_.data_</ValuePointer>
            </ArrayItems>
        </Expand>
    </Type>

    <!-- other stuff that isn't gsl::span ... -->
</AutoVisualizer>  

CMakeLists.txt


if (CMAKE_VERSION VERSION_GREATER 3.7.8)
    if (MSVC_IDE)
        option(VS_ADD_NATIVE_VISUALIZERS "Configure project to use Visual Studio native visualizers" TRUE)
    else()
        set(VS_ADD_NATIVE_VISUALIZERS FALSE CACHE INTERNAL "Native visualizers are Visual Studio extension" FORCE)
    endif()

    # add natvis file to the library so it will automatically be loaded into Visual Studio
    if(VS_ADD_NATIVE_VISUALIZERS)
        target_sources(GSL INTERFACE
            ${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis
        )
    endif()
endif()