Heresy 在 2015 曾經簡單介紹過《C++ Core Guidelines》(官方)了。而實際上,他的整份文件很多條目,老實說要全部看過(理解)要相當的時間,也有相當的難度,所以 Heresy 後來其實也沒很認真去碰。
如果對內容有興趣的話,可以參考「Modernes C++」這個網站(連結),他有針對 C++ Core Guidelines 撰寫了大量的文章(分類),應該算是可以輔助閱讀的資料。
當時也有提到,為了讓開發者可以快速地做到 guideline 的內容,除了既有的標準函式庫 STL 可以用之外,他們也另外定義了 Guidelines Support Library(GSL)這套 Header only 的函式庫(官網)來做為輔助。
而目前主要的 GSL 的實作,則是微軟提供的(GitHub),目前版本是 2.0.0,應該算是已經相當成熟了,理論上只要是有支援 C++14 的平台都可以使用。
根據文件的說法,GSL 分成五個主要的部份:
這邊的分類感覺上其實也只是概略分類,和 GSL 內部的結構沒有關係;實際上,就是各自有一些型別、函式可以使用了~
這部分簡單的說明,可以參考《C++ Core Guideline: The Guideline Support Library》這篇文章。
如果認真看的話,也會發現其實裡面有的是現有的 STL 就已經有的(smart pointer),也有部分是已經決定未來會納入標準的(std::span、參考)。
這邊 Heresy 就大概列一些個人覺得比較可能會用到的東西吧~
- 安全的型別轉換:narrow<T>()、narrow_cast<T>()
- 自動程式內資源的清理:finally()
- 限制指標不能是 nullptr:not_null<T>
- 明確代表資源擁有者的指標:owner<T>
- 語意更明確的條件檢查:Expects()、Ensures()
- 把陣列封包起來傳遞用的 span<T>(以前似乎曾經叫做 array_view<T>)
其中,以 owner<T> 來說的話,如果進去看程式碼(gsl/pointers),就會發現實際上它只是一個別名而已,並沒有什麼功能。不過藉由這樣的別名,它可以用來強調,到底誰該負責去釋放這個指標所指到的資源。
例如在《I.11: Never transfer ownership by a raw pointer (T*
) or reference (T&
)》(頁面)中,就有舉例,如果直接回傳一個指標的話,會讓人不知道接下來誰該刪除這個指標。
X* compute(args) // don't { X* res = new X{}; // ... return res; }
一個解決方法,就是使用 smart pointer,讓他可以自動處理刪除的問題。
而另一種解法,就是透過 owner<X*> 來取代 X*,明確地告訴使用者,接收這個指標的會是所有者。
owner<X*> compute(args) // It is now clear that ownership is transferred { owner<X*> res = new X{}; // ... return res; }
這樣的寫法在語意上相當明確,同時也不會有任何的效能影響;缺點呢,就是還是得要自己手動去釋放資源了~
而如果 IDE、或是靜態分析工具有支援 GSL 這樣的語法的話,那也可以做更好的分析,提醒開發者各種可能的狀態。
之後應該會花點時間來針對其中幾項來寫了。