この記事のポイント

  • IWYU(Include What You Use)の基本思想を理解する
  • C++における依存管理問題の背景を整理する
  • IWYUツールの使い方、導入手順、実務上の注意点を解説

そもそもC++の依存はなぜ崩壊しやすいのか?

C++は長年にわたってヘッダーファイル依存地獄に悩まされてきた言語です。
典型的な問題は次のようなものです。

  • 使わないヘッダーが無意識にインクルードされ続ける
  • インクルード順序が壊れるとビルドエラーになる
  • ビルド速度が遅くなる
  • 循環依存でモジュール分割が困難になる

こうした問題は「人間が手動でヘッダーを整理する」ことの限界を示しています。ビルドエラーが出なくても、依存は常に膨張し続けるのが現実です。

ここで登場するのがIWYUです。

Include What You Useとは?

IWYU (Include What You Use) とは:

自分が直接使用するシンボルのヘッダーだけをインクルードし、間接的な依存には頼らない

という依存整理の原則、かつそれを自動化支援するツール群です。

IWYUが目指す姿

  • 必要なヘッダーだけをインクルード
  • 不要なヘッダーは除去
  • 前方宣言で置き換え可能なものは前方宣言に
  • ビルド安定性の高い依存構造を維持

これにより、設計意図に沿った綺麗なヘッダー依存グラフが得られます。

IWYUが発見してくれる典型パターン

  • 「入っていないけど必要なインクルード」
    → コンパイラが他のヘッダー経由で偶然拾っていた依存

  • 「使っていないのに入っているインクルード」
    → 過去の実装変更で不要になったヘッダー

  • 「前方宣言で十分なのにヘッダーをインクルードしている箇所」

IWYUの動作仕組み(概念理解)

IWYUは以下の流れで解析します:

  1. コンパイルコマンドを収集
    compile_commands.jsonからビルド設定を取得
  2. ASTを生成してコードを静的解析
    → 各識別子がどのヘッダーに定義されているかを逆引き
  3. ヘッダー提案を出力
    → 「必要」「不要」「置換可能」の一覧を出す

IWYUの導入手順

ここからは実務上の導入手順を整理します。

ステップ1:ビルドシステムを整備

まずはcompile_commands.jsonが出力できる状態を作ります。
CMakeを使っているなら、以下で生成できます。

cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .

ステップ2:IWYUバイナリを用意

Ubuntu系ならapt経由で取得可能です。

sudo apt install include-what-you-use

macOSならHomebrewで入ります。

brew install include-what-you-use

バージョンに応じてビルドが必要な場合はソースからインストールも可能です。

ステップ3:iwuy_tool.pyで一括実行

IWYUは通常個別に起動しますが、大規模プロジェクトでは iwyu_tool.py が便利です。

python3 path/to/iwyu_tool.py -p .

出力例:

/path/to/AuditLogger.h should add these lines:
#include <string>

The following files should remove these lines:
- #include <fstream>
- #include <iostream>

ステップ4:fix_includes.pyで自動反映(慎重に)

IWYUは提案結果を修正スクリプトで自動適用する仕組みも持っています。

python3 fix_includes.py < iwyu_output.txt

自動適用は誤検出リスクがあるため、レビュー運用に組み込むなら事前にdiff確認を推奨します。

IWYUで扱いに注意が必要なケース

テンプレート型

テンプレート型は実体化される場面で完全型が必要になるため、IWYU提案が少し過剰になるケースがあります。

#include <vector> // vectorは前方宣言不可

マクロ・定義系

マクロ定義は宣言元追跡が困難なため、適用外になりがちです。

PIMPLイディオム

PIMPL構造は前方宣言と相性が良いですが、IWYUが過剰にヘッダー追加を提案することもあります。

サードパーティライブラリ

内部実装が不透明なライブラリではヘッダー依存をあえて緩くしておく場合もあります。
無理にIWYU適用するとビルドが壊れる例もあります。

実務での適切な運用方法

運用形態 推奨度 コメント
CI自動実行 差分をPRコメント等で通知
定期バッチ実行 週次・月次で全体クリーニング
導入初期に一括実行 ただし大規模コードは要注意
開発者個別利用 手元でIWYU実行してからPR出す

CIに組み込む際は「修正を提案するだけ」にとどめ、自動反映は避ける方が安定します。
GitHub Actionsでの統合事例も多数あります。

IWYUをレビュー観点に活かすには

  • PRレビューで「そのヘッダーは必要?」を自然に指摘可能に
  • ツール適用でレビュー観点を定式化し属人性を低減
  • ヘッダー構造レビューが設計レビューの入り口になる

まとめ

IWYUは単なる静的解析ツールではありません。依存設計そのものを見直すための思考補助装置です。

  • 責務を超えた依存は追加しない
  • 使う側が明示的にinclude責任を負う
  • レビューで定式化し、CI組み込みで継続適用する

こうした原則が定着すれば、C++特有の「依存がじわじわ腐敗していく」現象に歯止めがかかります。
結果として設計がシンプル化し、ビルド時間も安定します。