原文连接: 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::binding
。shell
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
转成bool
的literal
, 使用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了。