对于许多 C++ 开发人员来说,如果编译器爆出了大量的编译错误,且错误之间还没有明显的关联,这可就不好玩了。
如果开发环境可以提供更容易理解的错误提示和诊断体验,则开发人员就更加容易的找到错误原因并修复它。
我曾经写了一篇文章 “Concepts Error Messages for Humans”,里面探索了一些新的编译错误呈现的新思路,现在,感谢许多在 Visual Studio 上工作的人的辛勤工作,我们有更好的体验与大家分享。
在 VS2022 v17.8 预览版3 中,如果你使用 MSVC 构建一个 MSBuild 工程,在错误列表中将会显示更加丰富的关于此错误条目的信息。
>> 请移步至 www.topomel.com 以查看图片 <<
点击按钮,一个新的窗口将会显示出来。在默认情况下,它会显示在错误列表相同的位置,但如果你拖动它,则 VS 会记住它最后的显示位置。
>> 请移步至 www.topomel.com 以查看图片 <<
新的窗口我们叫做 问题详情 窗口,该窗口可以提供有关给定问题发生原因的详细结构化信息。如果我们看这些信息,我们可能会想,好吧,为什么 pet(dot) 无法被调用?如果单击它旁边的箭头,你就可以看到原因。
>> 请移步至 www.topomel.com 以查看图片 <<
以类似的方式,我们可以展开其他箭头以查找有关错误的更多信息。此示例由使用 C++20 Concepts 的代码生成,问题详情窗口提供了一种了解错误详细信息的方法。
>> 请移步至 www.topomel.com 以查看图片 <<
对于那些想要使用这个例子代码的用户,生成这些错误所需的代码是:
>> 请移步至 www.topomel.com 以查看图片 <<
记得,请使用 /std:c++20 编译开关进行编译。
输出窗口
作为这项工作的一部分,我们还使输出窗口可视化输出诊断中的任何层次结构。例如,在通过构建上一个示例生成的摘录中:
>> 请移步至 www.topomel.com 以查看图片 <<
这项功能使扫描大型诊断信息集变得更加容易,而不会丢失。
代码分析
问题详情窗口现在还用于具有关联事件的代码分析警告。例如,考虑以下代码,它可能会导致一个 use-after-move 错误。
>> 请移步至 www.topomel.com 以查看图片 <<
如果 should_eat 为真,should_reset 为假,则 my_string 将在移动后使用,这可能会导致不良行为。
幸运的是,我们的静态分析器捕获了此问题,在错误列表中创建了一个条目:
>> 请移步至 www.topomel.com 以查看图片 <<
看到 详细信息 列中的该图标了吗?这意味着有额外的信息。一起来看看:
>> 请移步至 www.topomel.com 以查看图片 <<
这告诉我们静态分析器遵循的过程,得出了可以在此程序中使用移自对象的结论。对于像这样的小函数,我们可能自己解决这个问题,但对于更大或更复杂的函数,Key Events 可以帮助你理解为什么你的代码会收到警告。
如何配置
默认情况下,当你双击或按回车键时,问题详情窗口也将打开,该条目具有关联的详细信息。这可以在文本编辑器> C/C++ > 高级>错误列表>>双击显示问题详细信息的工具>选项中进行配置。
>> 请移步至 www.topomel.com 以查看图片 <<
可以在“项目”>“属性”>“高级”>“启用 MSVC 结构化输出”中启用或禁用整个功能。你可以通过创建一个 Directory.Build.props 文件来影响多个项目,该文件将 UseStructuredOutput 属性定义为 true 或 false。
>> 请移步至 www.topomel.com 以查看图片 <<
工作原理
这项工作利用了SARIF(静态分析结果交换格式)标准。这是一种基于 JSON 的格式,用于以结构化方式表示诊断,使编译器能够在向 IDE 发送信息时保留许多诊断中固有的层次结构。
访问这些数据不需要其他编译器标志,但如果希望编译器在 SARIF 中生成诊断以便将结果与外部工具一起使用,则可以将 /experimental:log 标志传递给 MSVC。
总结
当编译我的小代码时,显然用不上这类”大炮”类工具,但是如果你正在开发举世瞩目的”大玩意儿”,则丰富的,更加有意义的错误信息,将会是你的福音。
最后
Microsoft Visual C++团队的博客是我非常喜欢的博客之一,里面有很多关于Visual C++的知识和最新开发进展。大浪淘沙,如果你对Visual C++这门古老的技术还是那么感兴趣,则可以经常去他们那(或者我这)逛逛。
本文来自:《Structured Diagnostics in the New Problem Details Window》