web-dev-qa-db-ja.com

C ++モジュール用に準備するC ++を記述する方法

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

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

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

54
user7610

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

clang: http://clang.llvm.org/docs/Modules.html MS VS 2015: http://blogs.msdn.com/b/vcblog/archive/2015/ 12/03/c-modules-in-vs-2015-update-1.aspx

マイクロソフトのアプローチは、主にマイクロソフトが現在のclangの人々よりも多くのリソースを実装に投入しているため、最も注目を集めているようです。 https://llvm.org/bugs/buglist.cgi?list_id=100798&query_format=advanced&component=Modules&product=clang を参照してくださいCまたは特にObjective Cは、実際のコードでははるかに使いやすいように見えます。 Visual Studioの最大かつ最も重要な顧客であるMicrosoftは、大量の内部ビルドスケーラビリティの問題を解決し、Microsoftの内部コードが存在する場所でコンパイルするのが最も難しいC++であるため、モジュールを強く求めています。 MSVC以外(たとえば、clangまたはGCCで40k行の関数をコンパイルできるようになれば幸いです)。そのため、Googleなどで使用されているclangビルドトリックはMicrosoftには提供されておらず、それらを後で修正するよりも早く修正する必要があります。

これは、実際の大規模なコードベースに実際に適用した場合、Microsoftの提案に重大な設計上の欠陥がないと言っているわけではありません。ただし、Gabyはモジュール用にコードをリファクタリングする必要があるビューであり、私は同意しませんが、彼がどこから来たのかはわかります。

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

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

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

多くの人々にとって非常に驚くべきことは、現在実装されると予想されるC++モジュールがこれらの区別を保持していることです。したがって、上記のall three最初はC++モジュールが期待するもののように見え、最後はより便利なプリコンパイル済みヘッダーのように見えます。これらのバリアントをサポートする必要があるのは、ほとんどの同じプリプロセッサメカニズムを再利用して、C++モジュールもほとんど追加の作業なしでサポートできるためです。

後のVisual Studioでは、モジュール定義ファイル(.ifcファイル)をリソースとしてDLLにリンクできます。これにより、最終的にMSVCでの.libと.dllの区別の必要性がなくなります。単一の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++カンファレンスでそれを見ることを期待してください:)

26
Niall Douglas

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

いいえ、できません。いくつかの#ifdefこのような魔法:

#ifdef CXX17_MODULES
    ...
#else
    #pragma once, #include "..." etc.
#endif

しかし、これはまだ.hをサポートするため、すべての利点が失われます。さらに、コードベースは非常に見苦しくなります。

このアプローチを採用したい場合は、「CXX17_MODULES "は、モジュールを使用する小さなテストプログラムを選択したビルドシステムでコンパイルし、コンパイルが成功したかどうかを確認できるように全員にグローバルを定義することです。

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

場合によります。もしあなたのプロジェクトがエンタープライズであり、あなたに食べ物を提供するなら、それがstable舎でリリースされてから広く適応されるようになるまで数年待つでしょう。一方、プロジェクトが最先端を行く余裕がある場合は、必ずモジュールを使用してください。

基本的には、Python3とPython2、またはそれほど重要ではないがPHP7とPHP5でも同じです。優れた最新のプログラマーであることと、Debianで迷惑にならないことのバランスをとる必要があります;-)

3
rr-