C++ モジュールの提案 (最新のドラフト)について読んでいますが、それが解決しようとしている問題を完全には理解していません。
あるコンパイラによってビルドされたモジュールを他のコンパイラ (もちろん同じ OS/アーキテクチャ上) で使用できるようにすることが目的ですか? つまり、この提案は C++ ABI の標準化に相当しますか?
そうでない場合、C++ ABI を標準化し、コンパイラの相互運用を可能にする別の提案が検討されていますか?
C++ モジュールの提案 (最新のドラフト)について読んでいますが、それが解決しようとしている問題を完全には理解していません。
あるコンパイラによってビルドされたモジュールを他のコンパイラ (もちろん同じ OS/アーキテクチャ上) で使用できるようにすることが目的ですか? つまり、この提案は C++ ABI の標準化に相当しますか?
そうでない場合、C++ ABI を標準化し、コンパイラの相互運用を可能にする別の提案が検討されていますか?
プリコンパイル済みヘッダー (PCH) は、特定のコンパイラが .cpp ファイル用に生成できる特別なファイルです。それらはまさにそれです:プリコンパイルされたソースコード。これらは、コンパイラを介して供給され、コンパイラに依存する形式に組み込まれたソース コードです。
PCH は、一般的にコンパイルを高速化するために使用されます。一般的に使用されるヘッダーを PCH に入れてから、PCH を含めるだけです。PCH でa を実行する#include
と、コンパイラは実際には通常の #include 作業を行いません。代わりに、これらのコンパイル済みシンボルをコンパイラに直接ロードします。C++ プリプロセッサを実行していません。C++ コンパイラを実行していません。#100 万の異なるファイルを含める必要はありません。1 つのファイルが読み込まれ、シンボルがコンパイラのワークスペースに直接完全に形成されて表示されます。
モジュールは完全な形の PCH であるため、すべてを言及します。PCH は基本的に、実際のモジュールを許可しないシステムの上に構築された巨大なハックです。モジュールの最終的な目的は、ファイルを取得し、シンボルを含むコンパイラ固有のモジュール ファイルを生成し、必要に応じて他のファイルがそのモジュールをロードできるようにすることです。シンボルは事前にコンパイルされているため、繰り返しますが、一連のものを #include したり、コンパイラを実行したりする必要はありません。コードは、import thing.foo
と表示されます。
STL から派生した標準ライブラリ ヘッダーを調べます。例を挙げてみましょう<map>
。このファイルが巨大であるか、結果のファイルを巨大にする他のファイルの #includes が多数含まれている可能性は十分にあります。これは、発生しなければならない多くの C++ 解析です。その中にあるすべての.cpp ファイルに対して発生する必要があります#include <map>
。ソースファイルをコンパイルするたびに、コンパイラは同じものを再コンパイルする必要があります。以上。オーバー。そしてもう一度。
<map>
コンパイル間で変更はありますか? いいえ、しかしあなたのコンパイラはそれを知ることができません。したがって、再コンパイルし続ける必要があります。.cpp ファイルに触れるたびに、この .cpp ファイルに含まれるすべてのヘッダーをコンパイルする必要があります。それらのヘッダーまたはそれらのヘッダーに影響を与えるソース ファイルには触れていませんが。
PCH ファイルは、この問題を回避する方法でした。しかし、それらは単なるハックであるため、制限があります。.cpp ファイルに最初に含める必要があるため、.cpp ファイルごとに 1 つだけ含めることができます。また、PCH は 1 つしかないため、PCH を変更する (新しいヘッダーを追加するなど) 場合は、その PCH 内のすべてを再コンパイルする必要があります。
モジュールは基本的にクロスコンパイラ ABI とは何の関係もありません (ただし、それらの 1 つがあると便利であり、モジュールを使用すると定義が少し簡単になります)。それらの基本的な目的は、コンパイル時間を短縮することです。
モジュールは、Java、C#、および他の多くの最新の言語が提供するものです。今日のヘッダーにあるコードは、インクルードされるたびに何度も解析する必要がないため、コンパイル時間が大幅に短縮されます。と言うと#include <vector>
、 の内容が<vector>
現在のファイルにコピーされます。#include
本当にコピー&ペーストに他なりません。
モジュールの世界では、単に例を言うだけimport std.vector;
で、コンパイラはそのモジュールのクエリ/シンボル テーブルをロードします。モジュール ファイルは、コンパイラが簡単に解析して使用できる形式になっています。また、モジュールがコンパイルされるときに一度だけ解析されます。その後、コンパイラによって生成されたモジュール ファイルに対して、必要な情報が照会されます。
モジュール ファイルはコンパイラによって生成されるため、コンパイラの C++ コード (AST) の内部表現にかなり密接に結びついており、おそらく移植性がありません (今日の.o
/ .so
/.a
ファイルのように、名前マングリングなどのため. )。
C++ のモジュールは、主に今日のソリューションよりも優れたものでなければなりません。つまり、ライブラリが *.so ファイルと *.h ファイルと API で構成されている場合です。彼らは、今日の #includes に関する問題を解決する必要があります。つまり、次のとおりです。
Xeo の言うことにもかかわらず、モジュールは Java や C# には存在しません。実際、これらの言語では、「モジュールのロード」は「OK、ここに CLASSPATH があり、それを検索して、ソースファイルが実際に使用するシンボルを提供する可能性のあるモジュールを見つける」ことに依存しています。Java での「インポート」宣言は、「モジュール要求」ではありません。C++ での「使用」と同じです (Java での「インポート ns.ns2.*」は、C++ での「名前空間 ns::ns2 の使用」と同じです)。 . そのようなソリューションは C++ では使用できないと思います。私が想像できる最も近い概算は、Vala のパッケージまたは Tcl のモジュール (8.5 バージョンのもの) です。
C++ モジュールをクロスプラットフォームにすることも、動的にロードすることもできないと思います (専用の C++ 動的モジュール ローダーが必要です - 不可能ではありませんが、今日定義するのは難しいです)。それらは間違いなくプラットフォームに依存し、要求に応じて構成可能にする必要があります。しかし、現在の C++ ABI と同様に、安定した C++ ABI は実際には 1 つのシステムの範囲内でのみ必要です。