C++ モジュールが長年の実装困難により標準からの削除を求める声が高まる

BigGo コミュニティ部
C++ モジュールが長年の実装困難により標準からの削除を求める声が高まる

C++ プログラミングコミュニティは、この言語の最も野心的な機能の一つについて前例のない議論を目の当たりにしている。C++20 がモジュールを導入してから5年以上が経過した今、開発者や専門家の間でこの機能を標準に残すべきかどうかを疑問視する声が高まっている。

この論争は厳しい現実から生じている。長年の開発努力にもかかわらず、C++ モジュールはコンパイル時間を劇的に短縮するという主要な約束を果たすことができていない。かつて C++ の悪名高いビルド速度問題の解決策として歓迎されたものが、現代的な C++ の実践を採用しようとする開発者にとってフラストレーションの源となっている。

実現しなかった性能の約束

C++ モジュールが最初に提案された時、主な売り文句は明確だった - 大幅なコンパイル速度の改善である。従来のヘッダーインクルードシステムは O(N²) アルゴリズムを作成し、同じコードが複数のソースファイル間で繰り返し解析される。モジュールは、前処理されたコードをバイナリ形式で保存し、ディスクから迅速に読み込めるようにすることで、この問題を解決するはずだった。

しかし、実際のテストでは異なる結果が明らかになった。現在の実装では、最良のケースでも10-20%程度の控えめな改善しか示されておらず、当初約束された変革的な向上には程遠い。コミュニティの一部のメンバーは、慎重に設計された標準ライブラリなどの既存の技術により、モジュールが導入する複雑さを必要とせずに4倍のコンパイル速度向上を既に達成できることを発見している。

プリコンパイル済みヘッダーという、はるかに古い技術が、大幅に少ない実装の複雑さでしばしば同等またはより良い性能向上を提供することを考慮すると、状況はさらに懸念される。これは、モジュールに投資された膨大なエンジニアリング努力が価値があったかどうかについて根本的な疑問を提起する。

現在のモジュール性能と期待値の比較

  • 当初の約束: 5倍-10倍のコンパイル速度向上
  • 現在の現実: 最良のケースでも10-20%の改善
  • プリコンパイル済みヘッダー: 多くの場合、同等またはより良い性能
  • 代替ソリューション: ZapCC は既存技術を使用して5倍以上の速度向上を実現

コンパイラ間での実装の混乱

モジュールの展開における最も有害な側面の一つは、コンパイラベンダーとビルドシステム開発者間の連携不足である。各主要コンパイラがモジュールを異なって実装しており、一つのツールチェーンで動作するコードが別のツールチェーンでは失敗する可能性がある断片化されたエコシステムを作り出している。

統合の課題は非常に深刻で、ビルドシステムはコンパイル中に追加のコンパイラフラグを生成し、それらを一時ファイルに保存し、後続のコンパイルコマンドに渡さなければならない。この複雑さのレベルは、モジュールが C++ 開発にもたらすはずだった優雅なシンプルさとは対照的である。

「コンパイラをビルドシステムに変えたくない」は、モジュール統合を改善する提案に直面した際のコンパイラ開発者からの一般的な回答となっており、システムをシームレスに動作させる責任を誰も取りたがらない膠着状態を効果的に作り出している。

すべての動く部品に対する権限を持つ統一された製品オーナーの不在は、多くの人が複雑さの kafkaesque な悪夢と表現する状況を作り出している。コンパイラチーム、ビルドシステム保守者、標準ライブラリ実装者間の調整を行う権限を持つ人がいなければ、モジュールは部分的な機能の状態に留まったままである。

主要な実装上の課題

  • コンパイラの分断化: 各ベンダーがモジュールを異なって実装している
  • ビルドシステムの統合: 複雑な一時ファイル管理が必要
  • 移植性の問題: モジュールバイナリファイルがコンパイラ間で移植できない( MSVC を除く)
  • ツールチェーンサポート: Apple のモジュールサポートは依然として「部分的」と記載されている
  • レガシーコード: 同一プロジェクト内で include <vector>import <vector> を混在させることができない

代替アプローチからの学び

コミュニティの議論では、より成功していたかもしれないいくつかの代替アプローチが強調されている。一部の開発者は、20年以上前にクリーンなモジュールシステムを実装し、現在も確実に動作し続けている D プログラミング言語を指摘している。D のアプローチには、モジュールを真に分離され予測可能にするクローズドネームスペースやセマンティック独立性などの機能が含まれている。

その他の提案は、はるかに少ない複雑さで利点の大部分を提供できたであろう、より単純な解決策に焦点を当てている。include のように動作するがコンテキストリークのない単純な import 文は、重要なコンパイラ最適化を可能にしながら、はるかに簡単に実装できたであろう。

ZapCC のようなツールは、永続的なコンパイラプロセスを通じて5倍以上のコンパイル速度向上を達成し、既存の技術を使用して劇的なビルド時間の改善が既に可能であることを実証している。これらの解決策は、より複雑なモジュールアプローチを支持してほぼ無視された。

今後の道筋

議論が激化する中、いくつかの潜在的な結果が議論されている。一部は、標準からモジュールを完全に削除し、より単純なアプローチで新たに始めることを主張している。その他は、一般的なモジュールの完全な複雑さを必要とせずに標準ライブラリの使用に意味のある利点を提供できる import std サブセットに焦点を当てることを提案している。

根本的な課題は、モジュールがそれぞれ独自の優先事項と制約を持つ複数の独立した組織間の広範な調整を必要とすることである。モジュールを適切に動作させるための明確なガバナンス構造と共有されたコミットメントがなければ、この機能は永続的に半実装のままかもしれない。

C++ コミュニティは今、困難な選択に直面している。期待を一貫して満たすことができなかった機能にリソースを投資し続けるか、実装の課題を認めて開発者が切実に必要としているコンパイル速度の改善を提供できる代替アプローチを追求するかである。

参考: Nibble Stew