C++ Core ガイドライン チェッカーの使用
C++ Core Guidelines は、C++ の専門家と設計者によって作成された C++ でのコーディングに関するガイドライン、ルール、ベスト プラクティスの移植可能なセットです。 現在、Visual Studio では、C++ 用のコード分析ツールの一部として、これらのルールのサブセットがサポートされています。 Visual Studio 2017 と Visual Studio 2019 では、Core Guideline Checkers が既定でインストールされています。 これらは、Visual Studio 2015 用の NuGet パッケージとして利用できます。
C++ Core Guidelines Project
Bjarne Stroustrup などによって作成された、C++ Core Guidelines は、最新の C++ を安全かつ効果的に使用するためのガイドです。 ガイドラインでは、スタティック型の安全性とリソースの安全性を重視しています。 それらでは、言語の最もエラーが発生しやすい部分を排除または最小化する方法を特定しています。 また、コードをよりシンプルにし、信頼性を高め、パフォーマンスを向上させる方法も提案しています。 これらのガイドラインは、標準 C++ Foundation によって管理されています。 詳細については、ドキュメント、C++ Core Guidelines を参照し、GitHub で C++ Core Guidelines プロジェクト ファイルにアクセスしてください。
Code Analysis で C++ Core Check Guidelines を有効化する
C++ Core Check ルールのサブセットは、Microsoft ネイティブ推奨ルール セットに含まれています。 これは、コード分析が有効になっているときに既定で実行されるルール セットです。
プロジェクトでコード分析を有効にするには
プロジェクトの [プロパティ ページ] ダイアログを開きます。
[構成プロパティ]>[コード分析] プロパティ ページを選択します。
[ビルドに対するコード分析の有効化] チェックボックスを選択します。
その他のコア チェック ルールを有効にするには、ドロップダウン リストを開き、含めるルール セットを選択します。
C++ Core Check ルールのサブセットは、Microsoft ネイティブ推奨ルール セットに含まれています。 これは、Microsoft Code Analysis が有効になっているときに既定で実行されるルール セットです。
プロジェクトでコード分析を有効にするには
プロジェクトの [プロパティ ページ] ダイアログを開きます。
[構成プロパティ]>[コード分析] プロパティ ページを選択します。
[ビルドに対するコード分析の有効化] および [Microsoft Code Analysis の有効化] プロパティを設定します。
サポートされているすべての C++ Core Check ルールを実行するか、独自のサブセットを選択して実行することもできます。
その他のコア チェック ルールを有効にするには
プロジェクトの [プロパティ ページ] ダイアログを開きます。
[構成プロパティ]>[コード分析]>[Microsoft] プロパティ ページを選択します。
[アクティブなルール] ドロップダウン リストを開き、[複数のルール セットを選択する] を選択します。
[ルール セットの追加または削除] ダイアログ ボックスで、含めるルール セットを選択します。
例
次に示すのは、C++ Core Check ルールで検出された問題の例です。
// CoreCheckExample.cpp
// Add CppCoreCheck package and enable code analysis in build for warnings.
int main()
{
int arr[10]; // warning C26494
int* p = arr; // warning C26485
[[gsl::suppress(bounds.1)]] // This attribute suppresses Bounds rule #1
{
int* q = p + 1; // warning C26481 (suppressed)
p = q++; // warning C26481 (suppressed)
}
return 0;
}
この例では、C++ Core Check ルールで検出されたいくつかの警告を示しています。
C26494 は "ルール Type.5: オブジェクトを常に初期化" です。
C26485 は "ルール Bounds.3: 配列からポインターへの減衰なし" です。
C26481 は "ルール Bounds.1: ポインター算術演算を使用しない" です。 代わりに
span
を使用してください
C++ Core Check Code Analysis ルール セットをインストールして有効にしてから、このコードをコンパイルします。 Code Analysis は、最初の 2 つの警告を出力し、3 つ目を抑制します。 Visual Studio 2015 のコード例のビルド出力を次に示します。
1>------ Build started: Project: CoreCheckExample, Configuration: Debug Win32 ------
1> CoreCheckExample.cpp
1> CoreCheckExample.vcxproj -> C:\Users\username\documents\visual studio 2015\Projects\CoreCheckExample\Debug\CoreCheckExample.exe
1> CoreCheckExample.vcxproj -> C:\Users\username\documents\visual studio 2015\Projects\CoreCheckExample\Debug\CoreCheckExample.pdb (Full PDB)
c:\users\username\documents\visual studio 2015\projects\corecheckexample\corecheckexample\corecheckexample.cpp(6): warning C26494: Variable 'arr' is uninitialized. Always initialize an object. (type.5: http://go.microsoft.com/fwlink/p/?LinkID=620421)
c:\users\username\documents\visual studio 2015\projects\corecheckexample\corecheckexample\corecheckexample.cpp(7): warning C26485: Expression 'arr': No array to pointer decay. (bounds.3: http://go.microsoft.com/fwlink/p/?LinkID=620415)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
C++ Core Guidelines は、より優れた、より安全なコードを作成するのに役立ちます。 ただし、ルールまたはプロファイルを適用すべきではないインスタンスが見つかる場合があります。 コード内でそれを直接抑制するのは簡単です。 [[gsl::suppress]]
属性を使用すると、C++ Core Check が次のコード ブロックの任意のルール違反を検出および報告し続けるようにできます。 個々のステートメントをマークして、特定のルールを抑制できます。 特定のルール番号を含めず [[gsl::suppress(bounds)]]
を作成することで、境界プロファイル全体を抑制することもできます。
サポートされているルール セット
C++ コア ガイドライン チェッカーに新しい規則が追加されると、既存のコードに対して生成される警告の数が増える可能性があります。 定義済みのルール セットを使用して、有効にするルールの種類をフィルター処理できます。 ほとんどのルールについての関連記事は、Visual Studio C++ Core Check リファレンスにあります。
算術ルール: 算術オーバーフロー、符号付きまたは符号なし演算、ビット操作を検出するルール。15.6
境界ルール: C++ Core Guidelines の境界プロファイルが適用されます。15.3
クラス ルール: 特殊なメンバー関数と仮想仕様の適切な使用に重点を置くいくつかのルール。 これらは、クラスとクラス階層に推奨されるチェックのサブセットです。15.5
コンカレンシー ルール: 不良ガード オブジェクト宣言をキャッチする単一のルールです。 詳細については、コンカレンシーに関連するガイドラインを参照してください。15.5
定数ルール: C++ Core Guidelines の定数関連チェックが適用されます。15.3
宣言ルール: グローバル変数の宣言方法を重視したインターフェイス ガイドラインの 2 つのルール。15.5
列挙型ルール: これらのルールではC++ Core Guidelines の列挙型関連チェックが適用されます。16.3
試験段階ルール: これらは試験段階にある C++ Core Check ルールで、有用ではあるものの、日常的に使用する準備が整っていません。 お試しいただき、フィードバックをお寄せください。16.0
関数ルール:
noexcept
指定子の導入に役立つ 2 つのチェック。 これらは、明確な関数の設計と実装に関するガイドラインの一部です。15.5GSL ルール: これらのルールでは、C++ Core Guidelines のガイドライン サポート ライブラリに関連するチェックが適用されます。15.7
有効期間ルール: これらのルールでは、C++ Core Guidelines の有効期間プロファイルが適用されます。15.7
所有者ポインター ルール: C++ Core Guidelines の所有者 <T> に関連するリソース管理チェックが適用されます。15.3
生ポインター ルール: C++ Core Guidelines の生ポインターに関連するリソース管理チェックが適用されます。15.3
共有ポインター ルール: これは、リソース管理ガイドラインの適用の一部です。15.5 共有ポインターを関数に渡す方法、またはローカルで使用する方法に固有のルールをいくつか追加しました。
STL ルール: これらのルールでは、C++ Core Guidelines の C++ 標準ライブラリ (STL) に関連するチェックが適用されます。15.7
スタイル ルール: 単純ですが重要なチェックの 1 つで、goto の使用を禁止します。15.5 これは、C++ でのコーディング スタイル、式とステートメントの使用を改善するための最初のステップです。
型ルール: C++ Core Guidelines の型プロファイルが適用されます。15.3
一意ポインター ルール: C++ Core Guidelines の一意ポインター セマンティクスを持つ型に関連するリソース管理チェックが適用されます。15.3
C++ Core Check ルール: このルール セットには、試験的なルールを除き、C++ Core Guidelines の現在実装されているすべてのチェックが含まれています。
15.3 これらのルールは、Visual Studio 2017 バージョン 15.3 で初めて登場しました
15.5 これらのルールは、Visual Studio 2017 バージョン 15.5 で初めて登場しました
15.6 これらのルールは、Visual Studio 2017 バージョン 15.6 で初めて登場しました
15.7 これらのルールは、Visual Studio 2017 バージョン 15.7 で初めて登場しました
16.0 これらのルールは、Visual Studio 2019 バージョン 16.0 で初めて登場しました
16.3 これらのルールは、Visual Studio 2019 バージョン 16.3 で初めて登場しました
警告は、1 つまたは少数のグループに制限することを選択できます。 ネイティブ最小およびネイティブ推奨ルール セットには、C++ Core Check ルールとその他の PREfast チェックが含まれます。
使用可能なルール セットを表示するには、[プロジェクト プロパティ] ダイアログを開きます。 [プロパティ ページ] ダイアログ ボックスで、[構成プロパティ]>[コード分析]>[全般] プロパティ ページを選択します。 次に、[ルール セット] コンボ ボックスのドロップダウンを開いて、使用可能なルール セットを表示させます。 ルール セットのカスタム組み合わせを作成するには、[複数のルール セットを選択する] を選択します。 [ルール セットの追加または削除] ダイアログには、選択できるルールが一覧表示されます。 Visual Studio のルール セットを使用する際の詳細については、「ルール セットを使用して実行する C++ ルールを指定する」を参照してください。
使用可能なルール セットを表示するには、[プロジェクト プロパティ] ダイアログを開きます。 [プロパティ ページ] ダイアログ ボックスで、[構成プロパティ]>[コード分析]>[Microsoft] プロパティ ページを選択します。 次に、[アクティブなルール] コンボ ボックスのドロップダウンを開いて、使用可能なルール セットを表示させます。 ルール セットのカスタム組み合わせを作成するには、[複数のルール セットを選択する] を選択します。 [ルール セットの追加または削除] ダイアログには、選択できるルールが一覧表示されます。 Visual Studio のルール セットを使用する際の詳細については、「ルール セットを使用して実行する C++ ルールを指定する」を参照してください。
マクロ
C++ Core Guidelines Checker には、コード内の警告のカテゴリ全体を簡単に抑制可能にするマクロを定義するヘッダー ファイルが付属しています。
ALL_CPPCORECHECK_WARNINGS
CPPCORECHECK_TYPE_WARNINGS
CPPCORECHECK_RAW_POINTER_WARNINGS
CPPCORECHECK_CONST_WARNINGS
CPPCORECHECK_OWNER_POINTER_WARNINGS
CPPCORECHECK_UNIQUE_POINTER_WARNINGS
CPPCORECHECK_BOUNDS_WARNINGS
これらのマクロは、ルール セットに対応し、警告番号のスペース区切りの一覧に展開されます。 適切なプラグマ コンストラクトを使用すると、プロジェクトまたはコードのセクションに関連するルールの効果的なセットを構成できます。 次の例では、コード分析によって、不足している定数修飾子のみが警告されます。
#include <CppCoreCheck\Warnings.h>
#pragma warning(disable: ALL_CPPCORECHECK_WARNINGS)
#pragma warning(default: CPPCORECHECK_CONST_WARNINGS)
属性
Microsoft C++ コンパイラでは、[[gsl::suppress]]
属性のサポートが制限されています。 関数内の expression および block ステートメントの警告を抑制するために使用できます。
// Suppress only warnings from the 'r.11' rule in expression.
[[gsl::suppress(r.11)]] new int;
// Suppress all warnings from the 'r' rule group (resource management) in block.
[[gsl::suppress(r)]]
{
new int;
}
// Suppress only one specific warning number.
// For declarations, you might need to use the surrounding block.
// Macros are not expanded inside of attributes.
// Use plain numbers instead of macros from the warnings.h.
[[gsl::suppress(26400)]]
{
int *p = new int;
}
コマンド ライン オプションを使用した分析の抑制
#pragmas の代わりに、ファイルのプロパティ ページのコマンド ライン オプションを使用して、1 つのプロジェクトまたは 1 つのファイルの警告を抑制することができます。 たとえば、ファイルの警告 C26400 を無効にするには、次のようにします。
ソリューション エクスプローラーでファイルを右クリックし、[プロパティ] を選択します。
[プロパティ ページ] ダイアログ ボックスで、[構成プロパティ]>[C/C++]>[コマンド ライン] プロパティ ページを選択します。
[追加のオプション] 編集ボックスに、
/wd26400
を追加します。
コマンド ライン オプションを使用すると、/analyze-
を指定することによって、ファイルのすべてのコード分析を一時的に無効にできます。 警告 D9025 "/analyze" を "/analyze e-"' にオーバーライドするが表示されます。これにより、後でコード分析を再度有効にするよう通知されます。
特定のプロジェクト ファイルで C++ Core Guidelines Checker を有効にする
焦点を絞ったコード分析を行いながら、Visual Studio IDE を使用すると便利な場合があります。 大規模なプロジェクトでは、次のサンプル シナリオを試してみてください。 ビルド時間を節約し、結果のフィルター処理を簡単に行うことができます。
コマンド シェルで、
esp.extension
環境変数を設定します。この変数を継承するには、コマンド シェルから Visual Studio を開きます。
プロジェクトを読み込み、そのプロパティを開きます。
コード分析を有効にし、適切なルール セットを選択しますが、コード分析拡張を有効にしないでください。
C++ Core Guidelines Checker を使用して分析するファイルに移動し、そのプロパティを開きます。
[構成プロパティ]>[C/C++]>[コマンド ライン]>[追加オプション] を選択し、
/analyze:plugin EspXEngine.dll
を追加しますプリコンパイル済みヘッダー ([構成プロパティ] > [C/C++] > [プリコンパイル済みヘッダー]) の使用を無効にします。 拡張機能エンジンがプリコンパイル済みヘッダー (PCH) から内部情報を読み取ろうとする可能性があるため、これは必要です。 PCH が既定のプロジェクト オプションを指定してコンパイルされた場合は、互換性がありません。
プロジェクトをリビルドします。 共通の PREFast チェックはすべてのファイルで実行する必要があります。 C++ Core Guidelines Checker は既定では有効になっていないため、これを使用するように構成されたファイルでのみ実行する必要があります。
Visual Studio の外部で C++ Core Guidelines Checker を使用する方法
自動ビルドの C++ Core Guidelines チェックを使用できます。
MSBuild
ネイティブ Code Analysis チェッカー (PREfast) は、カスタム ターゲット ファイルによって MSBuild 環境に統合されています。 プロジェクトのプロパティを使用して有効にし、C++ Core Guidelines Checker (PREfast に基づく) を追加することができます。
<PropertyGroup>
<EnableCppCoreCheck>true</EnableCppCoreCheck>
<CodeAnalysisRuleSet>CppCoreCheckRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
Microsoft.Cpp.targets
ファイルをインポートする前に、これらのプロパティを必ず追加してください。 特定のルール セットを選択するか、カスタム ルール セットを作成することができます。 または、他の PREfast チェックを含む既定のルール セットを使用します。
C++ Core Checker は、指定したファイルに対してのみ実行できます。 前述のものと同じ手法を使用しますが、MSBuild ファイルを使用します。 環境変数は、次のように BuildMacro
項目を使用して設定できます。
<ItemGroup>
<BuildMacro Include="Esp_Extensions">
<EnvironmentVariable>true</EnvironmentVariable>
<Value>CppCoreCheck.dll</Value>
</BuildMacro>
</ItemGroup>
プロジェクト ファイルを変更しない場合は、コマンド ラインで次のようにプロパティを渡すことができます。
msbuild /p:EnableCppCoreCheck=true /p:RunCodeAnalysis=true /p:CodeAnalysisRuleSet=CppCoreCheckRules.ruleset ...
MSBuild 以外のプロジェクト
MSBuild に依存しないビルド システムを使用する場合でも、チェッカーを実行できます。 使用するには、Code Analysis エンジンの構成の内部構造についてある程度理解しておく必要があります。 これらの内部構造のサポートは、今後のバージョンの Visual Studio では保証されません。
Code Analysis には、いくつかの環境変数とコンパイラのコマンド ライン オプションが必要です。 ネイティブ ツールのコマンド プロンプト環境を使用することをお勧めします。これにより、コンパイラの特定のパスの検索、ディレクトリのインクルードなどをする必要がなくなります。
環境変数
set esp.extensions=cppcorecheck.dll
これは、C++ Core Guidelines モジュールを読み込むようにエンジンに指示します。- Visual Studio 2019 以降では、
esp.annotationbuildlevel
環境変数を設定することは推奨されなくなりました。これは、設定すると誤検知が発生する可能性があるためです。 予期しない結果が表示される場合は、環境からこの変数を削除します。 set caexcludepath=%include%
標準ヘッダーで発生する警告を無効にすることを強くお勧めします。 ここでは、プロジェクトの共通ヘッダーへのパスなど、パスをさらに追加できます。
コマンド ライン オプション
/analyze
コード分析を有効にします (/analyze:only
と/analyze:quiet
の使用も検討してください)。/analyze:plugin EspXEngine.dll
このオプションは、Code Analysis Extensions エンジンを PREfast に読み込みます。 次に、このエンジンは C++ Core Guidelines Checker を読み込みます。
ガイドライン サポート ライブラリを使用する
ガイドライン サポート ライブラリ (GSL) は、ユーザーがコア ガイドラインに準拠するのを支援するように設計されています。 GSL には、エラーが発生しやすいコンストラクトをより安全な別のものと置き換えることができる定義が含まれています。 たとえば、パラメーターの T*, length
ペアを span<T>
型に置き換えることができます。 GSL プロジェクトは GitHub の https://github.com/Microsoft/GSL で入手できます。 ライブラリはオープン ソースであるため、ソースの表示、コメントの作成、または投稿を行うことができます。 また、vcpkg パッケージ マネージャーを使用して、ライブラリをローカルにダウンロードしてインストールすることもできます。
Visual Studio 2015 プロジェクトで C++ Core Check Guidelines を使用する
Visual Studio 2015 を使用する場合、既定では C++ Core Check コード分析ルール セットはインストールされません。 Visual Studio 2015 で C++ Core Check コード分析ツールを有効にする前に、他の手順が必要です。 Microsoft は、NuGet パッケージを使用した Visual Studio 2015 プロジェクトをサポートしています。 パッケージは Microsoft.CppCoreCheck という名前で、http://www.nuget.org/packages/Microsoft.CppCoreCheck で入手できます。 このパッケージを使用するには、Visual Studio 2015 更新プログラム 1 以降がインストールされている必要があります。
このパッケージでは、依存関係として別のパッケージ、ヘッダーのみのガイドライン サポート ライブラリ (GSL) もインストールされます。 GSL は GitHub の https://github.com/Microsoft/GSL でも入手できます。
Visual Studio 2015 内部でコード分析ルールが読み込まれる方法により、チェックする各 C++ プロジェクトに Microsoft.CppCoreCheck
NuGet パッケージをインストールする必要があります。
Visual Studio 2015 でプロジェクトに Microsoft.CppCoreCheck パッケージを追加するには
ソリューション エクスプローラーで、右クリックして、パッケージを追加するソリューション内のプロジェクトのコンテキスト メニューを開きます。 [NuGet パッケージの管理] を選択し、[NuGet パッケージ マネージャー] を開きます。
[NuGet パッケージ マネージャー] ウィンドウで、Microsoft.CppCoreCheck を検索します。
Microsoft.CppCoreCheck パッケージを選択し、[インストール] ボタンを選択して、プロジェクトにルールを追加します。
NuGet パッケージは、プロジェクトでコード分析を有効にすると呼び出される MSBuild
.targets
ファイルをプロジェクトに追加します。.targets
ファイルは、C++ Core Check ルールを Visual Studio Code 分析ツールの別の拡張機能として追加します。 パッケージがインストールされている場合は、[プロパティ ページ] ダイアログを使用して、リリースされたルールおよび試験的なルールを有効または無効にすることができます。