原文連接: 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了。