ビルドするとfatal error C1083が出る。でも、名指しされたヘッダーはディスクにちゃんとある。こういうときは、たいていファイルではなく検索パスのほうが原因です。
そんなときは、エラー行の先頭の語から読んでいきましょう。
C1083のエラー行の読み方
C1083の公式ページは、エラーの文面をfiletypeファイルを開けません: ‘file’: messageと書いています。先頭のfiletypeが入れ替わり、何を開こうとして失敗したのかを表します。
| 先頭の語 | 開けなかったもの | 最初に見る場所 |
| includeファイル | #includeに書いたヘッダー | ディレクティブの書き方と追加のインクルード ディレクトリ |
| プリコンパイル済みヘッダー ファイル | ビルドが作る .pch | プリコンパイル済みヘッダーの設定と出力先 |
| ソース ファイル | コンパイル対象の .cpp | プロジェクトのファイル一覧と、パスの引用符 |
ReproMain.cpp(10,10): error C1083: include ファイルを開けません。'SharedBanner.h':No such file or directory
この行は、実際にビルドして出したものです。山かっこ形式で取り込んでいるのに、追加のインクルード ディレクトリを1つも書いていないプロジェクトでビルドしました。ビルド ログに残った文字列をそのまま載せています。同じエラーが、先頭にfatalの付いた形で出ることもあります。3つめの「ソース ファイル」は、スペースを含むパスが途中で切れて渡されたときにも出ます。
引用符と山かっこで、探す場所が変わる
#include "LocalNote.h" // ソースと同じフォルダから探し始める
#include <SharedBanner.h> // 追加のインクルード ディレクトリから探す
/I(追加インクルード ディレクトリ)の説明には、探す順が3段で書かれています。二重引用符形式なら、まず #includeを書いたファイルと同じディレクトリから探します。見つからなければ、そのとき開かれているインクルード ファイルのディレクトリを、開かれたのとは逆の順にたどります。山かっこ形式のとき、またはローカル検索が失敗したときは、/Iで指定したディレクトリをコマンド ラインの順に探します。
INCLUDE環境変数が効くのは、cl.exeをコマンド ラインで動かす場合だけです。Visual Studioの開発環境では無視され、インクルード ディレクトリのプロジェクト プロパティの値が使われます。
ここでよくやるのは、サブフォルダのヘッダーを相対パスで書くときに、山かっこを使ってしまう形です。公式にも、headersというサブディレクトリに置いたヘッダーなら #include <headers\myheader.h> は失敗してC1083になり、#include “headers\myheader.h” なら機能すると書かれています。
もうひとつは、同じフォルダ名を検索パスとディレクティブの両方に書いてしまう形です。\path\example\headers\ を検索パスへ足したうえで #include <headers\myheader.h> と書くと、やはり見つかりません。どちらか一方からheadersを落とします。
追加のインクルード ディレクトリを $(ProjectDir) 基準で書く理由
設定する場所は、プロジェクトの[プロパティ ページ]にある[構成プロパティ] > [C/C++] > [全般] > [追加のインクルード ディレクトリ]です。複数のディレクトリはセミコロン(;)で区切ります。ここに絶対パスをそのまま書くと、そのパスが無い環境では指定が効きません。ヘッダーがそこにしか無ければ、またC1083です。

$(ProjectDir)Shared;%(AdditionalIncludeDirectories)
$(ProjectDir) はプロジェクトのディレクトリで、末尾の円記号(\)を含みます。そのため $(ProjectDir)Sharedと続けて書けば、プロジェクト直下のSharedフォルダになります。
末尾の %(AdditionalIncludeDirectories) は、いま継承している値を残すための書き方です。[親またはプロジェクトの既定値から継承]チェック ボックスをオフにすると、継承していた値は新しい値に置き換えられます。公式も、ほとんどの場合はオンのままにするよう案内しています。これを外して自分のフォルダだけを書くと、プロパティ シートから継承していたパスを失います。今度はそこにあったヘッダーでC1083が出ます。
Debugでは通るのにx64やReleaseだけC1083になるとき
この形は、設定を入れた対象がずれています。プロジェクトのプロパティの説明どおり、ほとんどのプロパティは構成ごとに持ちます。プロパティ ページで設定した値が効くのは、そのとき選んでいる構成とプラットフォームだけです。プロパティ ページ上部の[構成]と[プラットフォーム]を切り替え、同じ値が入っているかを1組ずつ見てください。アクティブでない構成もそのまま設定できます。
設定を直しても消えないとき、コンパイラが開いたファイルを見る
まず、コンパイラが探しに行った先を出力させます。[構成プロパティ] > [C/C++] > [詳細] > [インクルード ファイルの表示](/showIncludes)を有効にすると、取り込んだインクルード ファイルが1件ずつ出力され、入れ子は1レベルにつきスペース1つの字下げで示されます。目的のヘッダーの行があるか、あるならどのフォルダのものが採用されたかを見ます。
同じことは、ヘッダー自身に自分の居場所を名乗らせても確かめられます。引用符形式で書いたヘッダーと山かっこ形式で書いたヘッダーに、次の形の関数を1つずつ置きます。関数名はヘッダーごとに変えてください。同じ名前だと、両方を取り込んだ側で再定義になります。
inline const char* LocalNoteHeaderPath()
{
return __FILE__;
}
公式は __FILE__ を「現在のソース ファイルの名前」と定義し、ファイル名は現在の入力ファイルを参照すると書いています。つまり、この関数の __FILE__ は呼び出し側の .cppではなくヘッダー自身のパスです。実際に開かれたファイルの場所が、そのまま出ます。フルパスで出すには /FC([構成プロパティ] > [C/C++] > [詳細] > [完全パスの使用])が要ります。
/FCを有効にしてあるので、出てくるのは完全なパスです。そのまま載せると、使っている人のフォルダ名まで写ります。下の画面は、プロジェクト フォルダより上を *** へ置き換えて表示しています。伏せたのは表示だけで、ディスクの確認には元のパスを使っています。

配置が崩れたらビルドを止める仕掛けも書けます。__has_include(Visual Studio 2017バージョン15.3以降)は、そのヘッダーをインクルードできるかどうかをコンパイル前に判定します。
#ifdef __has_include
# if __has_include(<LocalNote.h>)
# error LocalNote.h が山かっこ形式で見つかっている。追加のインクルード ディレクトリを確認する
# endif
# if !__has_include(<SharedBanner.h>)
# error SharedBanner.h が山かっこ形式で見つからない。$(ProjectDir)Shared が外れている
# endif
#endif
判定がこの記事の説明と逆になったときだけ、#errorがビルドを止めます。検証構成はVisual Studio 2026 / Debug / x64 / Unicode / MFC共有DLLで、/W4の警告0件でビルドが通っています。
エラー行が .pchを指しているとき
このとき開けなかったのは、自分が書いたヘッダーではありません。ビルドが作る中間生成物のほうです。日本語版の出力は「プリコンパイル済みヘッダー ファイルを開けません。」で始まります。
公式は、プリコンパイル済みヘッダーを使う設定なら .pchが作成されている必要がある、と書いています。新しいプロジェクトではpch.cpp(Visual Studio 2017以前はstdafx.cpp)を最初にコンパイルして作ります。中間ファイルを消したあとや、構成を増やした直後に出たなら、まずリビルドで作り直します。
リビルドでも消えないときによく見るのは、.pchを作る側と使う側で設定が食い違っている形です。pch.h / stdafx.hの #includeが抜けているとC1010、古い .pchと .cファイルが混じっているとC1853になります。どちらもC1010 / C1853の記事で、ファイル単位の外し方まで扱っています。
C1083が出るのはコンパイルの段階です。公式も「コンパイラは、ファイルが見つからない場合にC1083エラーを生成します」と書いています。LNK1104のほうは、リンカーがファイルを読み書きするときに開けなかった場合の報告です。ヘッダーは通っていて .libが開けない、シンボルが見つからないなら、LNK1104 / LNK2019 / LNK2001の記事のほうが近道です。
まとめ
- まずエラー行の先頭の語を読む。includeファイル なら探す場所、プリコンパイル済みヘッダー ファイル ならPCHの設定と出力先、ソース ファイル なら渡っている引数を見る。
- サブフォルダのヘッダーを相対パスで書くなら二重引用符にする。検索パスへ足したフォルダ名を、ディレクティブ側にも重ねて書かない。
- 追加のインクルード ディレクトリは $(ProjectDir) 基準で書き、継承の値は残す。構成とプラットフォームの組ごとに入っているかを見る。
- それでも消えなければ /showIncludesで、コンパイラがどのファイルを開いたかを実測する。
