C++ Core Guidelines CheckerとGSLの導入

###### (An English translation is available [here](https://dev.to/tomoyukiaota/how-to-introduce-c-core-guidelines-checker-and-gsl--2b61).)

# 公開後の追記
この記事ではC++ Core Guidelines Checkerの導入をしていますが、このツールにはいくつか欠点があります。どうやら[clang-tidy](http://clang.llvm.org/extra/clang-tidy/)のほうが良さそうなので、そちらを導入したほうが良さそうです。（コメントにて、@tenmyo さんからclang-tidyについて教えて頂きました。）

C++ Core Guidelines Checkerの情報自体は、参考のために残しておきます。

# はじめに

## C++ Core Guidelines Checkerとは？

主にBjarne StroustrupとHerb Sutterによって、[C++ Core Guidelines](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)という、より良いC++のコードを書くために従うべきガイドラインが整備されています。このガイドラインの多くの項目は、解析ツールによって検証可能になるように書かれています。

C++ Core Guidelines Checkerとは、[C++ Core Guidelines](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)の項目を基にしたC++の静的解析ツールです。Microsoftによって開発されており、Visual Studio 2017であればデフォルトで使えます。（**追記：このツール以外にも、[clang-tidy](http://clang.llvm.org/extra/clang-tidy/)でもできます。**）このツールは、ビルドする際に、違反するコードについてError Listウィンドウにwarningを出力します。どのようなケースについてどのようなwarningを出力するかは、[Visual Studio C++ Core Guidelines Checker Reference | Microsoft Docs](https://docs.microsoft.com/en-us/visualstudio/code-quality/code-analysis-for-cpp-corecheck)に書かれています。

2018年5月現在、C++ Core Guidelines CheckerはWindows上のVisual Studioでのみ動作します。よって、この記事では導入方法やサンプルコードを用意していますが、その環境についてのみの話になります。


## GSLとは？
GSL (Guidelines Support Library)とは、[C++ Core Guidelines](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)において使うべきと定められた型や関数が含まれるライブラリです。どのような型や関数があるかについては、次の記事が詳しいので参考にして下さい。

- [C++ Core Guideline: The Guideline Support Library - ModernesCpp.com](http://www.modernescpp.com/index.php/c-core-guideline-the-guidelines-support-library)

GSLには複数の実装がありますが、この記事ではMicrosoftによる実装（[Microsoft/GSL](https://github.com/Microsoft/GSL)）を扱います。

なお、GSLは[複数のコンパイラをサポート](https://github.com/Microsoft/GSL#supported-platforms)しています。C++ Core Guidelines Checkerも独立したツールに切り出して、マルチプラットフォームで動作するようにしてほしいと思います・・・。

# 導入方法

## C++ Core Guidelines Checkerを有効にする

Visual StudioのProject毎に、C++ Core Guidelines Checkerの設定をします。有効にする具体的な方法や、一部のwarningを無効にする設定などは、以下のページに書かれているので参考にして下さい。

- [Using the C++ Core Guidelines checkers | Microsoft Docs](https://docs.microsoft.com/en-us/visualstudio/code-quality/using-the-cpp-core-guidelines-checkers)
- [C++ Core Guidelines Checker in Visual Studio 2017 | Visual C++ Team Blog](https://blogs.msdn.microsoft.com/vcblog/2017/08/11/c-core-guidelines-checker-in-visual-studio-2017/)
- [Managing warnings in the C++ Core Guidelines Checker | Visual C++ Team Blog](https://blogs.msdn.microsoft.com/vcblog/2017/08/14/managing-warnings-in-the-c-core-guidelines-checker/)

## GSLのコードをコピペ
[Microsoft/GSL](https://github.com/Microsoft/GSL)のREADMEにも書かれていますが、[gsl](https://github.com/Microsoft/GSL/tree/master/include/gsl)フォルダをコピペで持ってきます。ConanなどのPackage Managerには登録されてないんでしょうか・・・？

## GSLのwrapperの作成
現状のC++ Core Guidelines Checkerは、自分が書いたコード以外にも、サードパーティ製ライブラリのコードに対してもwarningを出力します。（この挙動は問題になっており、[Microsoftも対処しようとしている](https://stackoverflow.com/questions/45785126/selectively-disable-c-core-guidelines-checker-for-third-party-libraries)ようです。）具体的には、GSLを使おうとすると、GSLのコードに対してwarningを出力します。これでは、検査して欲しい自分のコードに対するwarningが埋もれてしまいますので、GSLのコードを検査の対象外にするために、GSLのwrapperを作成し、それを通して使うようにします。

GSLのwrapperは、以下のコードになります。`_MSC_VER`でifdefしている理由は、`CppCoreCheck/warnings.h`がVisual Studio 2017インストール時に作成されるファイルであることと、`#pragma`ディレクティブでwarningをdisableする際の書き方がMSVC特有のものだからです。

```cpp:gsl_wrapper.h
#ifdef _MSC_VER
#if _MSC_VER >= 1910
#include <CppCoreCheck/warnings.h>
#pragma warning(disable: ALL_CPPCORECHECK_WARNINGS)
#endif // _MSC_VER >= 1910
#endif // _MSC_VER


#include <gsl/gsl>


#ifdef _MSC_VER
#if _MSC_VER >= 1910
#pragma warning(default: ALL_CPPCORECHECK_WARNINGS)
#endif // _MSC_VER >= 1910
#endif // _MSC_VER
```

# サンプルコード
以上の導入方法をとると、次のGitHub repositoryのような構成になるはずです。
https://github.com/TomoyukiAota/CoreCheckerAndGsl


# おわりに
以上、C++ Core Guidelines CheckerとGSLの導入方法についてまとめました。C++ Core Guidelines CheckerについてはサポートしているプラットフォームがWindows上のVisual Studioのみ、GSLについてはgslフォルダのコピペといったスマートでないところがあり、まだまだ両者とも発展途上な感が否めません。しかし、C++ Core Guidelines Checkerが出力してくれるwarningや、GSLが提供する型や関数については、より良いC++のコードを書く上で一考の価値がありますので、より良いツール／ライブラリとして発展することを望みます。