C++と色々

主にC++やプログラムに関する記事を投稿します。

Visual C++で標準ヘッダや外部ヘッダを警告や診断の対象外とする方法

はじめに

コードを書くとき様々な理由*1コンパイラの警告レベルをできるだけ強くするべきです。コンパイラの警告だけではなく診断ツール類*2を使っている場合それらもできる限り厳しい設定にしておきたいです。

そんなときに困るのが、インクルードした標準ライブラリ内やサードパーティライブラリのヘッダ内に対する警告や診断表示です。 これらのコードは修正することができませんし、自分のコードだけを対象に検証を行ってほしいです。

以前も似たような内容の記事を投稿しました。

nekko1119.hatenablog.com

今回はこれよりもより良い方法を見つけたので紹介します。

/external コンパイラオプション

learn.microsoft.com

Visual Studio 2017 15.6以上で利用できます。また、VS2017&VS2019とVS2022では設定方法が少し異なります。VS2022では単にプロジェクトのプロパティに専用のプロパティページが設けられたかどうかだけの違いですが。 今回の記事は上記のMicrosoft Learnに書いてある内容と同じになりますので、一次情報が良い方はMicrosoft Learnを見てください。

1. 外部ヘッダを定義する

最初に検査の対象外とする外部ヘッダを定義する必要があります。 プロジェクトのプロパティを開いて、「外部インクルードディレクトリ」に含まれるパスが外部ヘッダになります。 デフォルトで標準ライブラリ(<stdlib.h><vector> など)が入っているパスと、Windows固有のライブラリ( <Windows.h><winrt/base.h> など)のパスが含まれています。

VC++ディレクトリの「外部インクルードディレクトリ」が外部ヘッダの対象となる

サードパーティのライブラリを使用してない場合は特に編集せずそのままでよいです。 なんらかのサードパーティライブラリ(boostとかcatch2とか)を利用している場合はそのライブラリのパスを「外部インクルードディレクトリ」に追加しましょう。

2. 外部ヘッダに対する振る舞いを指定する

VS2022では、プロパティの「C/C++」の「外部インクルード」ページで外部ヘッダに対する警告や診断の振る舞いを設定できます。VS2019やVS2017ではコマンドラインで直接オプションを指定します。 VS2022の場合の説明をします。

外部インクルードのページで外部ヘッダに対する振る舞いを定義できる

  • 山かっこでインクルードされたファイルを外部として扱う 「山かっこでインクルードされたファイルを外部として扱う」は、「外部インクルードディレクトリ」の定義とは別に #include するときに "" を使うか <> を使うかだけで外部かどうか判断するかどうかを設定することができます。 「外部インクルードディレクトリ」と「山かっこでインクルードされたファイルを外部として扱う」を両方設定したことがないので同時に設定するとどちらが優先されるのかは把握していません。 「外部インクルードディレクトリ」を使う場合、ここは「いいえ」でよいと思います。

  • 外部ヘッダーの警告レベル 「外部ヘッダーの警告レベル」は外部ヘッダに対してコンパイラの警告レベルを指定できます。イメージとしては

#pragma warning(push, <ここのレベル>)

#include <外部ヘッダ>

#pragma warning(pop)

のpushのレベルを指定するようなものです。 push : 0 相当にする場合は 「すべての警告を非表示にする(/external:W0)」にします。

  • 外部ヘッダーのテンプレート診断

関数テンプレートやクラステンプレートが外部ヘッダで定義されているとき、それらを自分のコードで利用してテンプレートのインスタンス化が自分のコード内で行われたときに、警告を出すかどうかの設定です。「いいえ」にしている場合外部ヘッダのテンプレートをインスタンス化したときに、それは警告の対象外になることがあるみたいです。基本的に「はい(/external:templates-」にして良い設定だと思います。

  • 外部ヘッダーの Code Analysis を無効にする 「外部ヘッダーの Code Analysis を無効にする」は外部ヘッダに対して診断ツール(IntelliSenseなど)の動作を設定できます。こちらもコンパイラの警告と同様に外部ヘッダを対象外にするならば「はい(/analyze:external-)」を設定すればよいです。

  • 外部ヘッダーの分析ルールセット 「外部ヘッダーの Code Analysis を無効にする」を「いいえ」にしている場合、つまり外部ヘッダの分析を有効にしている場合に、分析のルールを上書きすることができます。外部ヘッダの診断を無効にしている場合は空欄でよいでしょう。

以上で外部ヘッダ設定の説明になります。

終わりに

外部ヘッダの設定をすることで、コード内に #pragma をごちゃごちゃ書くことなくコードがスッキリしました!また、今までは /Wall を設定すると標準ライブラリ内で警告が大量に出ていたのですが、外部ヘッダを設定したら /Wall で標準ライブラリをインクルードしても警告や診断が出ないようになりました。最高です。

*1:バグが入りそうな危険なコードを早期検出したりより良いコード記述のプラクティスを身につけるなど

*2:IntelliSenseやclang-tidyやCppCoreCheckなど