自動現代化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了。

相關文章
相關標籤/搜索