VS CodeでCやC++を開発していると、#includeで指定したヘッダーファイルに赤い波線が表示されることがあります。
たとえば、次のようなコードです。
#include <iostream>
#include "sample.h"
このとき、VS Codeがヘッダーファイルの場所を正しく認識できていないと、#include errors detectedなどの警告が表示される場合があります。
MicrosoftのC/C++拡張機能では、ヘッダーファイルの検索先を指定するためにincludePathという設定を利用できます。
ただし、includePathは実際のコンパイラーに渡される設定ではありません。
主に、Microsoft C/C++拡張機能によるIntelliSense、コード解析、定義への移動などでヘッダーファイルを解決するために使われます。
そのため、VS Code上の赤い波線を消すための設定と、実際にプログラムをコンパイルするための設定は分けて考えることが重要です。
includePathを設定する前に確認すること
C/C++拡張機能をインストールする
includePathはVS Code本体の設定ではなく、Microsoftが提供しているC/C++拡張機能で使用されます。
VS Code左側の「拡張機能」から、次の拡張機能を検索します。
C/C++
提供元がMicrosoftになっているものをインストールしてください。
すでにコード補完や#includeのエラー表示が機能している場合は、インストール済みの可能性が高いです。
コンパイラーがインストールされているか確認する
CやC++を実行するためには、VS Codeとは別にコンパイラーが必要です。
Windowsでは、代表的に次のようなコンパイラーがあります。
MSVC
GCC
MinGW-w64
MSYS2 GCC
Clang
特に初心者の場合は、includePathを変更する前に、VS Codeが正しいコンパイラーを認識しているか確認することが重要です。
VS Codeで使用するコンパイラーを設定する方法
IntelliSense Configurationを選択する
まず、VS Codeで使用するコンパイラーを設定します。
次のショートカットでコマンドパレットを開きます。
Ctrl + Shift + P
続いて、次のコマンドを検索します。
C/C++: Select IntelliSense Configuration
インストールされているコンパイラーが検出されると、候補が表示されます。
たとえばMSYS2のUCRT64版GCCを使用している場合は、次のようなコンパイラーが表示されることがあります。
C:\msys64\ucrt64\bin\g++.exe
使用したいコンパイラーを選択します。
この設定によって、C/C++拡張機能はコンパイラーから標準ライブラリのヘッダー検索パスなどを取得できます。
compilerPathを確認する
より詳細に確認したい場合は、c_cpp_properties.jsonのcompilerPathを確認します。
MSYS2 UCRT64版GCCの場合は、たとえば次のようになります。
"compilerPath": "C:/msys64/ucrt64/bin/g++.exe"
compilerPathが正しく設定されていると、iostreamやvectorなどの標準ライブラリをVS Codeが自動的に認識しやすくなります。
そのため、次のようなコードに赤い波線が表示される場合は、まずincludePathよりcompilerPathを確認することをおすすめします。
#include <iostream>
#include <vector>
#include <string>
標準ライブラリのディレクトリを手動で大量にincludePathへ追加するよりも、正しいコンパイラーを指定するほうが適切です。
includePathをGUIから設定する方法
C/C++ Configurationsを開く
includePathはGUIから設定できます。
コマンドパレットを開きます。
Ctrl + Shift + P
次のコマンドを検索します。
C/C++: Edit Configurations (UI)
選択すると、「C/C++ Configurations」という設定画面が開きます。
Include pathにディレクトリを追加する
設定画面の中に「Include path」という項目があります。
ここに、ヘッダーファイルが保存されているフォルダーを追加します。
たとえば、プロジェクトが次の構成になっているとします。
MyProject
├─ include
│ └─ sample.h
└─ src
└─ main.cpp
この場合は、次のパスを追加できます。
${workspaceFolder}/include
${workspaceFolder}は、現在VS Codeで開いているプロジェクトのルートフォルダーを表します。
たとえば、次のフォルダーをVS Codeで開いている場合です。
C:\Users\user\Documents\MyProject
${workspaceFolder}/includeは、実質的に次の場所を意味します。
C:\Users\user\Documents\MyProject\include
絶対パスを直接書くよりも${workspaceFolder}を使ったほうが、別のPCや別のフォルダーへプロジェクトを移動しやすくなります。
c_cpp_properties.jsonからincludePathを設定する方法
JSONファイルを開く
GUIではなく、JSONを直接編集することもできます。
コマンドパレットを開いて、次を選択します。
C/C++: Edit Configurations (JSON)
通常は、プロジェクト内に次のファイルが作成されます。
.vscode/c_cpp_properties.json
includePathを記述する
たとえば、次のように設定できます。
{
"configurations": [
{
"name": "Windows GCC",
"includePath": [
"${workspaceFolder}/include"
],
"defines": [],
"compilerPath": "C:/msys64/ucrt64/bin/g++.exe",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "windows-gcc-x64"
}
],
"version": 4
}
この中の次の部分がincludePathです。
"includePath": [
"${workspaceFolder}/include"
]
複数のフォルダーを指定する場合は、次のように追加します。
"includePath": [
"${workspaceFolder}/include",
"${workspaceFolder}/src",
"C:/libs/MyLibrary/include"
]
参考サイト
【C言語/VSCode】インテリセンスの有効範囲を広げる(includePathの設定)
${workspaceFolder}/**の意味
/**を付けると再帰的に検索される
includePathでは、通常、指定したディレクトリだけが検索対象になります。
一方、パスの末尾に/**を付けると、その下にあるサブディレクトリも再帰的に検索できます。
たとえば、次の構成があるとします。
include
├─ sample.h
├─ math
│ └─ vector.h
└─ graphics
└─ image.h
次のように指定するとします。
"${workspaceFolder}/include/**"
この場合、includeだけでなく、その下にあるmathやgraphicsも検索対象になります。
${workspaceFolder}/**がすでに設定されている場合がある
C/C++拡張機能の設定によっては、最初から次のようなパスが指定されている場合があります。
"${workspaceFolder}/**"
この設定がある場合、ワークスペース内のヘッダーファイルはすでに検索対象になっていることがあります。
そのため、必ずしも${workspaceFolder}/includeを追加しなければならないわけではありません。
ただし、大規模なプロジェクトでは${workspaceFolder}/**によって検索範囲が広くなりすぎる場合があります。
そのような場合は、次のように必要なフォルダーだけ指定したほうが管理しやすくなります。
"includePath": [
"${workspaceFolder}/include",
"${workspaceFolder}/src"
]
外部ライブラリのincludePathを設定する方法
外部ライブラリのincludeフォルダーを追加する
OpenCVなどの外部ライブラリを利用する場合は、ライブラリのヘッダーファイルが保存されているフォルダーをincludePathへ追加します。
たとえば、次の場所にヘッダーファイルがあるとします。
C:\libs\opencv\include
この場合は次のように設定できます。
"includePath": [
"${workspaceFolder}/include",
"C:/libs/opencv/include"
]
さらに別のライブラリも使用する場合は、複数指定できます。
"includePath": [
"${workspaceFolder}/include",
"C:/libs/opencv/include",
"C:/libs/MyLibrary/include"
]
includePathとコンパイル時の-Iは別の設定
includePathはVS Code側の設定
ここは特に重要です。
たとえば、次のように設定したとします。
"includePath": [
"C:/libs/MyLibrary/include"
]
これによってVS CodeのIntelliSenseがヘッダーファイルを見つけられるようになっても、実際のコンパイラーがそのフォルダーを認識するとは限りません。
includePathは、Microsoft C/C++拡張機能側の設定です。
GCCやClangでは-Iを指定する
GCCやClangで外部ヘッダーを使用する場合は、コンパイル時にもインクルードパスを指定します。
たとえば、次のようにします。
g++ main.cpp -IC:/libs/MyLibrary/include -o main.exe
-Iは、GCCやClangに追加のヘッダー検索パスを指定するオプションです。
つまり、次のように役割が異なります。
includePath
→ VS CodeのIntelliSenseやコード解析
-I
→ 実際のコンパイラー
VS Code上では赤い波線が消えているのにコンパイルエラーになる場合は、実際のビルド設定に-Iが指定されているか確認してください。
tasks.jsonでインクルードパスを設定する方法
GCCをVS Codeから直接実行する場合
VS Codeのtasks.jsonを使ってGCCを実行している場合は、argsに-Iを追加します。
たとえば、プロジェクト構成が次のようになっているとします。
MyProject
├─ include
│ └─ sample.h
├─ src
│ └─ main.cpp
└─ .vscode
├─ c_cpp_properties.json
└─ tasks.json
tasks.jsonは次のように設定できます。
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "build",
"command": "g++",
"args": [
"${workspaceFolder}/src/main.cpp",
"-I",
"${workspaceFolder}/include",
"-o",
"${workspaceFolder}/main.exe"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
次の部分がコンパイラー用のインクルードパスです。
"-I",
"${workspaceFolder}/include"
一方、c_cpp_properties.jsonには次のように設定します。
"includePath": [
"${workspaceFolder}/include"
]
役割を整理すると次のようになります。
c_cpp_properties.json
→ IntelliSenseやコード解析
tasks.json
→ 実際のビルド
#includeの書き方とincludePathの関係
includePathの起点によって記述が変わる
たとえば次のプロジェクト構成があるとします。
MyProject
├─ include
│ └─ mylib
│ └─ sample.h
└─ src
└─ main.cpp
includePathを次のように設定した場合です。
"${workspaceFolder}/include"
この場合は、次のように書けます。
#include <mylib/sample.h>
一方、次のように設定した場合です。
"${workspaceFolder}/include/mylib"
次のように記述できます。
#include <sample.h>
つまり、どのフォルダーを検索の起点にするかによって、#includeで記述するパスも変わります。
“…”と<…>には違いがある
CやC++では、次の2種類の書き方があります。
#include "sample.h"
#include <sample.h>
一般的には、"..."は現在のソースファイル周辺なども検索対象にし、<...>は設定されたインクルード検索パスを中心に検索します。
ただし、厳密な検索順序は使用するコンパイラーによって異なります。
そのため、includePathだけで"..."と<...>の違いが決まるわけではありません。
iostreamなどに赤い波線が表示される場合
includePathよりcompilerPathを確認する
次のような標準ライブラリに赤い波線が表示される場合があります。
#include <iostream>
#include <vector>
#include <string>
この場合は、標準ライブラリの保存場所をincludePathへ直接追加するより、まずcompilerPathを確認してください。
MSYS2 UCRT64版GCCを使用する場合は、たとえば次のようになります。
"compilerPath": "C:/msys64/ucrt64/bin/g++.exe"
C/C++拡張機能は、設定されたコンパイラーを利用して標準ライブラリの検索パスなどを取得します。
そのため、標準ライブラリ関連のエラーでは、compilerPathを正しくすることが重要です。
include errors detectedが表示される場合の確認方法
順番に原因を確認する
VS Codeで次のようなエラーが表示されることがあります。
#include errors detected. Please update your includePath.
この場合は、次の順番で確認すると原因を特定しやすくなります。
- MicrosoftのC/C++拡張機能がインストールされているか確認する
- GCC、Clang、MSVCなどのコンパイラーがインストールされているか確認する
C/C++: Select IntelliSense Configurationで正しいコンパイラーを選択するcompilerPathが正しいか確認する- プロジェクト固有のヘッダーが
includePathに含まれているか確認する #includeの記述と実際のフォルダー構成が一致しているか確認する- 実際のコンパイル側にも
-Iなどが設定されているか確認する
特に、最初からincludePathを大量に追加するのではなく、まずコンパイラー設定を確認することが重要です。
CMakeを使用している場合
includePathを手動管理しない方法もある
CMakeを利用しているプロジェクトでは、c_cpp_properties.jsonへ大量のincludePathを手入力するより、CMakeの設定をIntelliSenseに反映させるほうが管理しやすい場合があります。
たとえば、CMakeLists.txtで次のように設定しているとします。
target_include_directories(
MyApp
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
)
この設定とは別に、c_cpp_properties.jsonにも同じパスを手入力すると、設定の二重管理になりやすくなります。
CMake ToolsなどのConfiguration Providerやcompile_commands.jsonを利用すると、実際のビルド設定をIntelliSenseへ反映しやすくなります。
compile_commands.jsonを利用する方法
実際のコンパイル設定をIntelliSenseに反映できる
compile_commands.jsonは、各ソースファイルをどのようなオプションでコンパイルするか記録したコンパイルデータベースです。
たとえば、次のような情報が含まれます。
使用するコンパイラー
-Iオプション
-Dによるマクロ定義
コンパイルオプション
c_cpp_properties.jsonでは、次のように指定できます。
{
"configurations": [
{
"name": "Windows GCC",
"compilerPath": "C:/msys64/ucrt64/bin/g++.exe",
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
}
],
"version": 4
}
小規模なプロジェクトでは必須ではありませんが、CMakeなどを利用する中規模以上のプロジェクトでは便利な方法です。
includePathとbrowse.pathの違い
includePathはヘッダー解決に使われる
includePathは、主にC/C++拡張機能のIntelliSenseが#includeを解決するために使用します。
browse.pathはTag Parserで使われる
一方、browse.pathはTag Parserがシンボル情報を収集する際に利用します。
たとえば、次のような設定です。
"browse": {
"path": [
"${workspaceFolder}/include"
]
}
ただし、browse.pathを省略した場合は、includePathの値が利用されます。
そのため、一般的な小規模プロジェクトでは、まずincludePathとcompilerPathを正しく設定すれば十分な場合が多いです。
WindowsとMSYS2での設定例
c_cpp_properties.jsonの例
MSYS2 UCRT64版GCCを使用し、次の構成になっているとします。
MyProject
├─ include
│ └─ app
│ └─ config.h
├─ src
│ └─ main.cpp
└─ .vscode
main.cppでは次のように記述します。
#include <iostream>
#include <app/config.h>
c_cpp_properties.jsonは、たとえば次のように設定できます。
{
"configurations": [
{
"name": "Windows GCC",
"includePath": [
"${workspaceFolder}/include"
],
"defines": [],
"compilerPath": "C:/msys64/ucrt64/bin/g++.exe",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "windows-gcc-x64"
}
],
"version": 4
}
実際のコンパイルは次のようにします。
g++ src/main.cpp -Iinclude -std=c++20 -o main.exe
VS Code側とコンパイラー側の対応は次のようになります。
VS Code
includePath = ${workspaceFolder}/include
GCC
-Iinclude
両方を適切に設定することで、IntelliSenseと実際のコンパイル結果の食い違いを減らせます。
VS CodeでincludePathを設定するときのポイント
VS CodeでincludePathを設定するときは、単にヘッダーのパスを大量に追加すればよいわけではありません。
まず、使用しているコンパイラーをVS Codeが正しく認識しているか確認することが重要です。
特に、iostreamやvectorなどの標準ライブラリが見つからない場合は、includePathではなくcompilerPathを確認してください。
プロジェクト独自のヘッダーや外部ライブラリについては、必要に応じて次のように設定します。
"includePath": [
"${workspaceFolder}/include"
]
一方、実際のGCCやClangでコンパイルする場合は、別途次のような設定が必要です。
-Iinclude
つまり、基本的には次のように理解すると分かりやすいでしょう。
compilerPath
→ 使用するコンパイラーをVS Codeに教える
includePath
→ IntelliSenseが追加で検索するヘッダーフォルダーを指定する
-I
→ 実際のコンパイラーにヘッダー検索先を指定する
小規模なC/C++プロジェクトであれば、この3つの違いを理解しておけば、VS Codeの#include関連トラブルの多くを解決しやすくなります。
以上、VS CodeのincludePathとはについてでした。
最後までお読みいただき、ありがとうございました。









