4

Clang と GCC (そしておそらく MSVC?) は、現在、モジュールの実装に 2 段階のコンパイルを使用しています。

  • BMI/CMI (MSVC の IPR、まだこれを行う場合は?) を生成して、他の誰かのインポートによって消費されます。
  • リンカにフィードするオブジェクト ファイルを生成します。

BMI/CMI を生成するがオブジェクト ファイルを生成しないモジュールには、いくつかの用途があるようです。たとえば、条件付きコンパイルに使用される型または constexpr 変数のみをエクスポートするモジュールです。

標準から理解できる限り、オブジェクトファイルを作成/リンクする必要があるとは言っていません。ですから、このようなモジュールの使用について明らかな何かを見落としているのではないかと考えています。また、ツールがこの「モジュールとしてビルドし、オブジェクトとしてビルドしない」ワークフローをサポートすることを期待している場合はどうでしょうか?

4

1 に答える 1

3

モジュールは、通常はヘッダーにはないものの定義を提供できると期待しています。

このモジュールを想像してください:

export module hello;

export inline auto say_hello() -> char const* {
    return "hello world";
}

ご覧のとおり、関数はインラインです。インターフェースにもあります。ヘッダーを使用すると、実装を配置する場所がありません。インライン関数を可能にするために、言語では複数の定義を見つけることができます。したがって、各 TU はオブジェクト ファイルに独自の定義を出力します。

それは、モジュールを使用して回避できる繰り返し作業です。ご覧のとおり、モジュール インターフェイスは他の cpp ファイルと同様に TU です。インライン関数をエクスポートする場合、実装は他の TU で使用できますが、すべての TU が実装を提供する必要はありません。これは、インライン関数を含む TU という 1 つの場所に配置できるためです。

constexpr 変数でも同じことが期待されます。また、それらへの参照またはアドレスを取得する可能性があるため、定義も必要です。たとえば、次のようにします。

export module foo;
import <tuple>;
export constexpr auto tup = std::tuple{1, 'a', 5.6f};
import foo;
int a = std::get<0>(tup);

このstd::get関数は、タプルへの参照を取ります。これは constexpr 変数ですが、一部のコンテキスト (特に最適化がない場合) では、変数を ODR で使用する必要がある場合があります。

したがって、私の例では、モジュールfooは constexpr 変数のみをエクスポートしますが、cpp ファイルが定義を含むオブジェクト ファイルにコンパイルされることを期待しています。


オブジェクト ファイル内に何もない場合もあります。また、今日は空の TU のように動作することも期待しています。

// I'm empty

cppこのようなファイルを問題なくプロジェクトに追加し、実行可能ファイルにリンクできます。ツールがモジュールと同じように動作することを期待しています。

于 2021-01-21T19:30:00.500 に答える