C++ モジュールに対応するために C++ をどのように記述すればよいですか? 質問する

C++ モジュールに対応するために C++ をどのように記述すればよいですか? 質問する

C++ モジュールをサポートするコンパイラはすでに 2 つあります。

今新しいプロジェクトを開始する場合、モジュール機能が最終的にコンパイラでリリースされたときにそれを採用できるようにするには、何に注意する必要がありますか?

モジュールを使用して、それをサポートしていない古いコンパイラとの互換性を維持することは可能ですか?

ベストアンサー1

C++モジュールをサポートするコンパイラはすでに2つある

カラン:モジュールMS VS 2015:http://blogs.msdn.com/b/vcblog/archive/2015/12/03/c-modules-in-vs-2015-update-1.aspx

Microsoft のアプローチは、最も注目を集めているようです。主な理由は、Microsoft が現在どの clang 開発者よりも多くのリソースを実装に投入しているためです。https://llvm.org/bugs/buglist.cgi?list_id=100798&query_format=advanced&component=Modules&product=clang私が言いたいのは、Modules for C++ には致命的なバグがいくつかあるのに対し、Modules for C、特に Objective C は実際のコードでははるかに使いやすそうだということです。Visual Studio の最大かつ最も重要な顧客である Microsoft は、Modules を強く推奨しています。Modules は、内部ビルドのスケーラビリティに関する多くの問題を解決します。また、Microsoft の内部コードは、存在する C++ の中でも最もコンパイルが難しいコードであるため、MSVC 以外のコンパイラーを使用することはできません (たとえば、clang や GCC で 4 万行の関数をコンパイルするのは困難です)。したがって、Google などが使用する clang ビルド トリックは Microsoft では利用できず、Microsoft は早急に修正する必要に迫られています。

これは、Microsoft の提案を実際の大規模なコード ベースに適用した場合、重大な設計上の欠陥がないということではありません。ただし、Gaby はモジュール用にコードをリファクタリングする必要があると考えています。私はこれに反対ですが、彼の考えは理解できます。

今新しいプロジェクトを開始する場合、モジュール機能が最終的にコンパイラでリリースされたときにそれを採用できるようにするには、何に注意する必要がありますか?

Microsoft のコンパイラが現在モジュールを実装することが期待されている限り、ライブラリがこれらすべての形式で使用可能であることを確認する必要があります。

  1. ダイナミックライブラリ
  2. 静的ライブラリ
  3. ヘッダーのみのライブラリ

多くの人にとって非常に驚くべきことは、現在実装されているC++モジュールではこれらの区別が維持されているため、C++モジュールのバリアントが次のように表示されることです。3つすべて上記の 2 つのうち、最初のものは C++ モジュールに期待されるものに最も似ており、最後のものはより便利なプリコンパイル済みヘッダーに最も似ています。これらのバリエーションをサポートすべき理由は、ほとんど同じプリプロセッサ機構を再利用して、ほとんど余分な作業なしで C++ モジュールもサポートできるためです。

今後の Visual Studio では、モジュール定義ファイル (.ifc ファイル) をリソースとして DLL にリンクできるようになります。これにより、MSVC での .lib と .dll の区別が不要になり、コンパイラに 1 つの DLL を提供するだけで、モジュールのインポート時にすべてが「そのまま機能」し、ヘッダーやその他のものは必要ありません。もちろん、これは COM に少し似ていますが、COM の利点のほとんどがありません。

モジュールを使用することは可能ですか単一のコードベースでそれをサポートしていない古いコンパイラとの互換性を維持できますか?

上に挿入した太字のテキストを意味していると仮定します。

答えは、一般的には「はい」です。プリプロセッサ マクロをさらに活用すれば、プリプロセッサは通常どおり動作するので、ヘッダー内で#include <someheader>に変換できますimport someheader。したがって、C++ モジュール サポートを使用して、次のような形式で個々のライブラリ ヘッダーをマークアップできます。

// someheader.hpp

#if MODULES_ENABLED
#  ifndef EXPORTING_MODULE
import someheader;  // Bring in the precompiled module from the database
// Do NOT set NEED_DEFINE so this include exits out doing nothing more
#  else
// We are at the generating the module stage, so mark up the namespace for export
#    define SOMEHEADER_DECL export
#    define NEED_DEFINE
#  endif
#else
// Modules are not turned on, so declare everything inline as per the old way
#  define SOMEHEADER_DECL
#  define NEED_DEFINE
#endif

#ifdef NEED_DEFINE
SOMEHEADER_DECL namespace someheader
{
  // usual classes and decls here
}
#endif

main.cpp などで、次のようにするだけです。

#include "someheader.hpp"

... コンパイラに /experimental:modules /DMODULES_ENABLED がある場合、アプリケーションは自動的にライブラリの C++ モジュール エディションを使用します。そうでない場合は、これまでどおりインライン インクルードが行われます。

これらは、コードをモジュール対応にするために必要な、ソース コードへの最小限の変更だと思います。ビルド システムについては何も言及していないことにお気づきでしょう。これは、これらすべてをシームレスに「動作」させるために作成した cmake ツールをまだデバッグしている最中であり、今後数か月はデバッグを続ける予定です。来年か再来年の C++ カンファレンスでご覧いただけると思います :)

おすすめ記事