在之前的文章中,我们介绍了 clang-tidy 工具,它可以检测代码中哪些地方可以使用新的 C++11/C++14/C++17 特性来实现 C++ 源代码的现代化。但是,我们如何轻松检测一个项目中哪些地方使用了新的 C++ 特性呢?
Facebook 和谷歌在其源代码中大量使用 C++11。正如我们在之前的文章中发现的,Facebook 的 Folly 库几乎使用了所有 C++11 特性。我很好奇微软是否也在其开源代码中使用新的 C++11 标准。
微软的开源项目可以在他们的GitHub仓库中找到;其中一些只是根据自身需求对其他项目进行的 fork,如 LLVM、Clang 和 OpenCV,另一些则是由他们自己开发的。让我们来看看其中一个项目,看看它是否采用了 C++11。一个不错的选择是微软最新开源的 C/C++ 项目之一:WinObjc。
Windows Bridge for iOS(也称为 WinObjC)是微软的一个开源项目,为 Visual Studio/Windows 提供 Objective-C 开发环境。此外,WinObjC 还提供对 iOS API 兼容性的支持。
检查 C++11 使用情况的一种方法是逐个查看每个源文件,这可能需要数小时甚至数天,具体取决于项目的规模。另一种解决方案是使用 Clang。
让 Clang 及其强大的诊断引擎来帮忙。
Clang 团队的目标是提供尽可能清晰、信息量大的错误消息。他们努力让这些消息对命令行编译器来说尽可能用户友好。为此,Clang 会精确指出代码中的问题所在。这是通过一个将错误信息加工为用户友好消息的诊断引擎来实现的。
Clang 会发出多种诊断信息,对于我们的需求来说,最有意思的是描述形如"XXX incompatible with C++98"(与 C++98 不兼容)的那些。
但是,我们如何获得 Visual Studio 解决方案的 Clang 诊断信息呢?
第一种选择是使用 Clang 编译您的项目;然而,这不是一件容易的事——事实上,您必须修改构建流程,用 Clang 替代微软编译器。
第二种选择是使用CppDepend来分析您的 Visual Studio 项目,它使用 Clang 作为前端解析器,并报告其所有诊断信息。CppDepend对开源社区免费。
下面是 WinObjC 解决方案的全部 Clang 诊断信息。

不过在我们的案例中,我们只需要"incompatible with C++98"类型的诊断;您可以轻松过滤前面的查询,只获取这些诊断:

我们可以看到,nullptr 和 auto 特性在源代码的许多地方被使用。然而,与 Facebook 和谷歌的项目不同,C++11 特性并未被广泛使用。浏览 WinObjC 的 C++ 源文件时,我们还可以看到该项目更多地使用了 C++/CX 扩展。
总结:
得益于 C++ 社区的出色工作,新的 C++ 标准如今正被越来越广泛地使用。其中许多新特性易于使用,对 C++ 代码进行现代化改造可以让它更易读、更易维护。
