在Visual Studio 2017中,我创建了一个调用C++函数的.natvis调试器可视化规则。

在调试器中,它显示:
This expression has side effects and will not be evaluated.
除此之外,它还显示了一个蓝色的小箭头,可以单击它以强制对其求值,然后它实际上确实调用了该函数。 (我认为这可能是最近的功能,因为我似乎记得在VS2013中尝试过此功能,并且不记得它有旁路功能)

我的问题是:有什么方法可以永久绕过此安全检查,以便它始终可以立即评估我的功能,而无需我单击箭头?

我看过一个非常类似的问题:"This expression causes side effects and will not be evaluated". How to suppress?,其中接受的答案仅对C#有效(在C#表达式的末尾添加,ac强制调试器自动重新评估它)

我想如果存在这种情况,它将是以下机制之一:

  • 始终禁用安全检查的注册表设置或其他全局设置。
  • 一种注释代码或.natvis规则的方法,以便编译器以某种方式知道它是安全且无副作用的纯函数

  • 要提供有关该应用程序的更多详细信息:我们在代码中的各处都使用了uint32,这些字符串是从字符串中哈希出来的,并且只有在开发版本中才加载了字符串数据库。解码功能在二进制搜索树中查找u32 ID,返回在存储的节点中找到的字符串。因此,我知道它是完全无副作用的并且足够快,以至于不会在每次.natvis规则这样说时仅调用该函数而影响调试经验。

    最佳答案

    经过进一步的研究,我怀疑没有办法告诉Visual Studio您的函数没有副作用,即使对于像int MyTestFunction() { return 56; }这样的琐碎无副作用的函数,它仍然会给出“表达式具有副作用,并且不会评估”消息。

    尽管这不是一个令人满意的答案,但是我确实找到了解决此问题的方法,该方法是使用尴尬,丑陋的XML语法重新实现我试图调用的功能(以我的情况为例,通过表进行二进制搜索) .natvis的CustomListItems标记。

    尽管此标签的名称暗示它与列表有关,但对于任何需要某种算法实现的可视化工具而言,此标签似乎都是一种包罗万象的东西。在<CustomListItems>下,您可以使用一堆不同的标记,这些标记可能足以实现几乎任何算法:

  • <Variable>标签来声明变量
  • <Loop>标记,用于迭代,
  • <Break Condition="myCondition">用于检查是否终止循环,
  • <Exec>标记,用于执行表达式,变异<Variable>标记
  • 中声明的变量的值
  • <If Condition="myCondition">用于分支
  • 您可以包括任意数量的<Item Name="name">value</Item>标记,它们中的每一个都会在监视窗口中以一行的形式显示在要扩展的变量下方。

  • 据我所知,大多数算法标记只能在CustomListItems下使用(我尝试使用一些<Expand>标记尝试常规的<Variable>规则,但出现错误,表明它不受支持)

    必须重新实现已经在这种可怕的语法中运行的C++函数并不是一件令人愉快的事情(请记住,因为它是XML,所以需要像使用o​​jit_code和&gt;代替&lt;>那样来获取陷阱)。

    但是,通过以下几点技巧,它并没有那么糟糕
  • 如果您在Visual Studio中编辑.natvis文件,则保存该文件会触发调试器重新评估显示,而无需重新启动程序,因此对.natvis规则进行迭代非常快。 (注意:从外部编辑器编辑.natvis文件时,这在VS2017中对我似乎不起作用)
  • 在规则中使用许多<标记,基本上可以完成“打印调试”的工作。在尝试使您的.natvis规则起作用时,请使用<Item>打印出中间值。如果算法无法正常运行,这将使查找算法失败的位置变得更加容易。在工作时,请删除这些多余的标签。

  • 您可以在此处找到文档和<Item>的示例。

    https://msdn.microsoft.com/en-us/library/jj620914.aspx

    关于c++ - "This expression has side effects and will not be evaluated."周围有办法吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47041809/

    10-13 07:51