致完美主义者:0个错误,0个警告
首先,我假定你是一个完美主义者。
在一个项目中,为了实现完美而干净利落的代码,你开启了最严格的的编译警告级别,或者使用了最为严格的代码分析规则,但对于那些不属于你的项目中的外部代码库,你还是会看到一大波编译警告,对于一个完美主义者来说,编译完成后没有看到”0错误0警告”是绝对不能接受的。
在Visual Studio 2019预览版中,我们提供了一种简单的方法来将这些头文件声明为外部头文件来解决这个问题。为了解决这个问题,我们的开发团队已经工作了好一阵子了,感谢这个开发工程中来自社区的帮助和意见反馈。当我们添加了添加外部头文件的实验功能的时候,我们还专门写过一篇文章来介绍这个功能。现在,我很高兴地宣布,感谢所有社区开发者反馈,外部头文件功能现已正式被编译器和代码分析器所支持,并已内建到集成开发环境中。
这些外部头文件可以自定义编译器的警告级别,代码分析规则和模板分析设定。这个自定义功能,可以让你自由地为工程代码选择严格的设置,以确保代码的质量,同时,也不会因为外部头文件的警告太多给你的完美主义带来障碍。
添加外部头文件到你的工程中
在你的工程的”VC++ 目录”中,有一个”外部包含目录”的属性,可以用来定义外部头文件所在的目录位置。这个属性会被正常地添加到头文件的搜索路径中,但是所有在这个目录中的头文件都将被视为外部头文件。从编译器的视角来说,你将不会感受任何不同之处,但是你可以为这些外部头文件设置不同的警告级别和其他代码分析级别。
在默认情况下,编译工具集和Windows SDK目录中的头文件都会被视为外部头文件。另外,你也可以添加任何其他的头文件目录(例如,一些第三方代码库)到这个属性中,多个目录路径可以使用一个分号区分。
请注意,这个新的属性会被之前版本的工具集忽略掉。如果你希望使用旧版本的编译器编译工程代码,你需要确保所有”外部包含目录”属性的值也必须包含在”包含目录”属性中,否则,旧版本的编译器就不会找到这些头文件位置。
为了保持兼容性,在Visual Studio 2019中,我们将会继续包含工具集和Windows SDK头文件在现有的”包含目录”属性中,但是在下个大版本中,它们将会从这个属性中移除。
自定义外部头文件的警告级别
你可以在工程属性对话框的”C/C++ > 外部包含目录”属性中自定义外部头文件的警告级别,如下图所示:
自定义外部头文件的代码分析设定
通过将头文件声明为外部头文件,也能让代码分析器使用起来得心应手。
下面的一个例子演示了如何在代码分析器中使用这项新特性。
从CAExcludePath到/external:*和/analyze:external*的迁移
为了能够禁用外部开源代码库中的一些不必要的警告信息,我们创建了一个临时解决方案来使用特殊的环境变量(“CAExcludePath”),该变量可用于指定目录哪个代码分析不会报告任何警告。
我们现在有一个更好的解决方案来控制外部头文件的代码分析行为。虽然我们决定保留“CAExcludePath”选项,但我们强烈建议切换到/external:* 和/analyze:external* 选项。
使用这些选项,可以关闭外部头文件的代码分析,或使用与代码库其余部分不同的分析规则集合。 这些都具有更好的可用性和可维护性,因为它们都可以通过Visual Studio集成开发环境中获得。
使用/analyze:external-和/external:*
请考虑下面的头文件和源文件,它里面没有特别的功能,只是我们故意放入了一些错误,如下图所示:
当使用默认选项进行分析时,我们会从头文件和源文件中获得函数的代码分析警告如下:
现在,如果我们将 externallib.h 的目录添加到“外部包含目录”,如下所示:
然后将“Disable Code Analysis for External Headers”设置为“Yes (/analyze:external-)”如下:
执行“运行代码分析”将不再报告来自外部头文件的任何代码分析警告:
根据模板参数,某些模板可能存在错误。 如果你想分析模板代码,即使它们在外部文件中,你可以将“外部头文件中的模板诊断”选项设置为“是 (/external:templates-)”。 现在,执行“运行代码分析”将报告模板函数的代码分析警告,即使它们在外部头文件中:
使用/analyze:external:ruleset 和 /external:*
现在可以通过使用“外部头文件的分析规则集”选项指定不同的规则集文件来分析具有与代码库其余部分不同的规则集的外部文件,而不是关闭外部文件的代码分析。
对于此示例,我创建了一个自定义规则集“ExternalHeaderRules”,它仅启用两个规则 C6021 和 C6385 作为警告。 然后我为“外部头文件的分析规则集”选项选择了它,如下图所示:
请注意,“禁用外部头文件的代码分析”选项设置为“否”,启用对外部头文件的代码分析。 通过此更改,代码分析现在将使用自定义“ExternalHeaderRules”规则集分析来自外部文件的函数,并报告以下警告:
当前,如果使用“外部头文件的分析规则集”,则会忽略“外部头文件中的模板诊断”选项。 我们计划更改行为以遵守该选项并将模板视为非外部模板,并应用通用规则集而不是外部头文件的规则集。
加分项:更好的代码分析性能
在我们研究此功能时,我们意识到一些内置检查器并没有真正跳过通过“CAExcludePath”环境变量排除的文件中的函数。
取而代之的是,它们像其他函数一样被分析,并且从这些函数中产生的警告被简单地过滤掉了。
随着我们添加对 /external:* 选项的支持,我们更新了它们以支持“CAExcludePath”以及 /external:* 和 /analyze:external- 选项,并跳过对来自排除或外部文件的函数的分析。
这导致在我们的生产代码库中观察到性能改进,从 25% 提升到了 30%。
实际的性能改进将取决于有多少代码库来自排除或外部头文件,以及有多少项目使用 PCH 等。
外部头文件和 Microsoft C++ 编译器
Microsoft C++ 编译器中添加了几个新标志,用于指定外部包含目录及其警告和代码分析设置。
如需了解这些标志如何使用,请参考具体的编译器文档。
总结
总有一些完美主义者,就是想要这东西:0个错误,0个警告。
挺好,我也想要。
最后
Microsoft Visual C++团队的博客是我非常喜欢的博客之一,里面有很多关于Visual C++的知识和最新开发进展。大浪淘沙,如果你对Visual C++这门古老的技术还是那么感兴趣,则可以经常去他们那(或者我这)逛逛。
本文来自:《Customized Warning Levels and Code Analysis for External Headers》
最近我写了个东西
正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。
- 下一篇: C++代码扫描基础知识
- 上一篇: STL可视化调试工具
相关推荐
- IContextMenu第三部分:调用位置
- Posted on 11月03日
- 深度理解:多个auto_ptr同时引用同一个资源对象下的释放问题及赋值问题
- Posted on 04月29日
- 实战经验:php-cgi.exe 进程意外退出
- Posted on 04月15日
- 实战经验:CentOS环境下搭建OpenCV开发环境
- Posted on 04月10日
评论已关闭。