有没有办法"这个表达有副作用,不会被评估."?

ugl*_*ote 5 c++ visual-studio natvis visual-studio-2017

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

在调试器中它显示:

This expression has side effects and will not be evaluated.

除此之外,它还显示了一个蓝色箭头,可以点击它以强制它进行评估,然后它实际上会调用该函数.(我认为这可能是最近的功能,因为我似乎记得在VS2013中尝试这个并且不记得它有旁路)

我的问题是:有什么方法可以永久地绕过这个安全检查,这样它总能立即评估我的功能而不需要我点击箭头?

我看了一个非常相似的问题: "这个表达会导致副作用,不会被评估".怎么压制?接受的答案仅对C#有效(在C#表达式的末尾添加ac,强制调试器自动重新评估它)

我想如果存在这样的事情,它将是以下机制之一:

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

要提供有关应用程序的更多详细信息:我们在代码中使用uint32,它们是从字符串中散列出来的,并且我们有一个仅在开发版本中加载的字符串数据库.解码函数在二叉搜索树中查找u32 ID,返回在存储节点中找到的字符串.所以我知道它完全没有副作用且足够快,每次.natvis规则都这样说时,它不会影响调试体验.

ugl*_*ote 6

经过进一步研究,我怀疑没有办法告诉 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++ 函数并不是一件令人愉快的事情(请记住一些陷阱,例如必须使用&gt;and&lt;代替>and<因为它是 XML)。

然而,通过以下几个技巧,事情并没有想象的那么可怕

  • 如果您在 Visual Studio 中编辑 .natvis 文件,则保存文件会触发调试器重新评估显示,而无需重新启动程序,因此迭代 .natvis 规则非常快。(注意:当我在 VS2017 中从外部编辑器编辑 .natvis 文件时,这似乎对我不起作用)
  • <Item>在规则中使用大量标签,您基本上可以执行相当于“打印调试”的操作。在尝试使 .natvis 规则发挥作用时,请使用<Item>打印出中间值。如果算法无法正常工作,这将使追踪算法失败的位置变得更加容易。当它工作时删除这些额外的标签。

您可以在此处找到文档和示例CustomListItems

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