ライブラリのいくつかの "クライアント"がC++ 11のみを使用していると仮定したライブラリを構築している場合、その内部用にC++ 14を使用してライブラリ自体をコンパイルできますか?
はい、一般的に可能です。
私は、GCCのファイルシステムTSの実装にぴったりです。 <experimental/filesystem>
ヘッダーは純粋なC++ 11で書かれており、C++ 11クライアントに含めることができますが、libstdc++fs.a
の実装はC++ 14で書かれています。
C++ 11と比べてAPI/ABI /リンクの互換性の問題はありますか?
はが自分のリンク時の互換性を破るためにの実装を必要とC++ 11とC++ 14の間には変更はありません。これは実装を意味するものではありませんは壊れませんが、必須ではありません。
GCCについては、constexpr
と下記のサイズ変更の問題を除いて、C++ 11とC++ 14は完全にAPIとABI互換ですと考えています。
パブリックAPIの特定の新機能を避けている限り、C++でライブラリを実装してビルドすることは安全ですか?もしそうなら、どうすればよいですか?
これはコンパイラによって異なりますが、理論的には可能です。
C++ 11で有効でないC++言語機能(関数戻り型の控除、auto
パラメータを持つ汎用ラムダ、変数テンプレートなど)とC++ 14ライブラリエンティティ、std::make_unique
、std::integer_sequence, or
std :: shared_timed_mutex`のようになります。
C++ 14のほぼすべての変更のリストはSD-6にあります。
注意すべきは、非静的なconstexpr
メンバー関数の意味がC++ 11とC++ 14の間で変更されたことです。 C++ 11では、このメンバー関数は、const
ある:
struct X {
constexpr int foo();
};
C++ 14には非constです。両方のC++ 11とC++ 14と互換性を持つようにするには、明示的const
としてそれを修飾する必要があります。
struct X {
constexpr int foo() const;
};
C++ 11とC++ 14の両方で同じことを意味します。
void operator delete(void*, std::size_t);
C++ 11クライアントコードは、その関数を定義している場合、あなたのライブラリはC++ 14でコンパイル:
もう一つ注意すべき点は、C++ 11とC++ 14には、この演算子が別の何かを意味していることですは通常のoperator delete(void*)
の代わりにそれを呼び出すことになり、おそらく間違ったことになります。これはおそらくであり、実際のコードではまったく問題はありませんが、可能です。 G ++とClangを使用すると、C++ 14のコードを-fno-sized-deallocation
でコンパイルして新しい機能を無効にすることができます。これにより、C++ 14のライブラリコードは決してそのバージョンのoperator delete
を呼び出すことはありません。
C++ 14の機能を使用していなくても、クライアントが同じコンパイラバージョンを使用している限り、おそらく動作させることができます。異なるバージョンのコンパイラを使用している場合、Visual Studioを使用すると確かに動作しません。 –
あなたの正確なコンパイラは何ですか?どのコンパイラがそれを消費するのですか? – Yakk
OSXのClang; LinuxではClangかgccのどちらかです。 Windows上のMSVS。引数のために、ライブラリとアプリケーションの両方が同じコンパイラと同じバージョンを使用すると仮定しましょう。私の質問は、私がライブラリに対して-std = C++ 14を使用できるかどうかと、-std = c +アプリで+11、パブリックAPIが動作させるために私が覚えておく必要がある具体的な事項 –