自动现代化C++代码

原文连接: http://hokein.me/clang-tools-...html

虽然C++11标准出来已经有好些年了,可是因为历史的缘由,如今大部分C++项目仍然是C++03的语法。那么有没方法可以自动地把老的C++03代码替换成C++11代码?从而让咱们享受到C++11新特性,像for-range loop,auto,nullptr,override等。git

答案固然有的——clang-tidy。clang-tidy提供一系列的modernize-*checks。这些checks就是用C++11改写C++03。具体有下面这些:github

  • modernize-avoid-bind: 使用lambda替换std::bindingshell

  • modernize-deprecated-headers: 将C标准库的头文件include替换成C++style,#include <assert.h> => #include <cassert>json

  • modernize-loop-convert: 使用for-range loop替换for(...;...;...;), 并更新for语句的相关变量。api

  • modernize-make-shared: 找出全部显式建立std::shared_ptr变量的表达式,并使用make_shared替换。app

  • modernize-make-unique: 跟make-shared同样,使用std::make_unique替换全部std::unique_ptr显式建立表达式。electron

  • modernize-pass-by-value: 在构造函数中使用move语义ide

  • modernize-raw-string-literal: 用C++11的raw string literal(R"...")替换原来的string literal, 这样的好处就是不用再添加转义符``了。函数

  • modernize-redundant-void-arg: 去掉void函数参数。

  • modernize-replace-auto-ptr: 用std::unique_ptr替换std::shared_ptr, std::shared_ptr是不推荐使用的,即便在C++98。

  • modernize-shrink-to-fit: 在C++03中,若是咱们想修改STL容器的capacity,只能经过copy & swap的方式,C++11提供了shink_to_fit的方法。

  • modernize-use-auto: 在变量定义的时候,使用auto代替显式的类型声明,这个在定义STL容器类的Iterator特别方便。

  • modernize-use-bool-literals: 找出全部隐式从int转成boolliteral, 使用true或者false代替。

  • modernize-use-default: 对于没有任何自定义行为(定义为{})的特殊的成员函数,构造函数,析构函数,移动/复制构造函数,用=default代替掉{}

  • modernize-use-emplace: 使用STL容器中的emplace代替push_back

  • modernize-use-equals-delete: 在C++98中,类设计为了实现禁止调用某些特殊的成员函数,一般把它们声明成private;在C++11中,只须要在声明中体检=delete,找出全部private的特殊成员函数,并将它们标记成=delete

  • modernize-use-nullptr: 用nullptr代替NULL

  • modernize-use-override: 对于子类改写父类的virtual方法,在方法后面添加override, 并删掉virtual前缀,即virtual void NewOveride() => void NewOverride() override {}

  • modernize-use-using: 用using代替typedef, 如typedef int V => using V = int

如何应用到项目中

这里将以GitHub的electron开源项目为例子,如何应用clang-tidy来改写它的C++03代码:

  • 你须要导出项目的compilation database, 一般命名为compile_commands.json, 由于clang-tidy做为一个clang-based工具,须要知道如何编译每个源文件(从compile_commands.json查找). ninja提供这个导出功能,只须要简单执行下面命令。对于其它不用ninja编译的项目,也是有工具导出的,方法请查看前一篇介绍clang-tidy文章

cd path/to/electron
# Make sure you can build electron successfully.
./script/build.py -c D
# Dump compilation database.
ninja -C out/D -t compdb cc cxx > compile_commands.json
  • 如今,咱们能够尝试对项目中某个文件运行modernize-use-nullptr check, 咱们须要添加-fix的命令参数,clang-tidy才会执行对原文件修改, 否则结果会定向到标准输出stdout

# Diagnose any `NULL` usage.
clang-tidy -checks="-*,modernize-use-nullptr" atom/browser/api/atom_api_menu.cc
# Replace all NULL usages to C++11 nullptr.
clang-tidy -checks="-*,modernize-use-nullptr" -fix atom/browser/api/atom_api_menu.cc
  • 咱们固然不须要每次都手动执行一个源文件,run_clang_tidy.py脚本可以对每一个compilation database中的每一个文件都运行clang-tidy(使用多进程方法)。

# Run `modernize-use-auto` on all files in atom/* and apply fixes.
path/to/run_clang_tidy.py -checks="-*,modernize-use-auto" -fix atom/*

真实运行的结果,请查看electron#6423,已经被merge进upstream了。

相关文章
相关标签/搜索