7

編集: インクルード ガードについては知っていますが、インクルード ファイルはここでは問題になりません。私が話しているのは、静的ライブラリに焼き付けられる、実際にコンパイルされ、すでにリンクされているコードです。

私は C++ で自分用の汎用ユーティリティ ライブラリを作成しています。

私が作成している関数の 1 つは、printFile、 requires stringcoutおよび標準ライブラリの他のメンバーです。

ライブラリがコンパイルされてから、 and も使用する別のプロジェクトにリンクされるstringと、とcoutのコードが複製されるのではないかと心配しています。プログラムがリンクされているライブラリバイナリで両方が事前にリンクされ、それら自体を使用するプロジェクトと再びリンクされます。stringcout

ライブラリは次のように構成されています。

  1. libname.hppライブラリを使用するプログラマーがプロジェクトで使用することになっているファイルが 1 つあります#include
  2. fnameで宣言されたすべての関数に対して、それを実装libname.hppするファイルがあります。fname.cpp
  3. すべてのfname.cppファイルも#include "libname.hpp".
  4. libname.aライブラリ自体は にコピーされてコンパイルされ/usr/lib/ます。

これは起こりますか?
はいの場合、それはまったく問題ですか?
はいの場合、どうすればこれを回避できますか?

4

4 に答える 4

3

ライブラリをコンパイルして、string と cout を使用する別のプロジェクトにリンクすると、string と cout のコードが重複するのではないかと心配しています。

心配しないでください。最新のコンパイル システムではそれができません。テンプレート関数のコードはオブジェクト ファイルに出力されますが、リンカーは重複するエントリを破棄します。

于 2012-12-31T02:05:22.013 に答える
3

標準 C++ ライブラリのライブラリ定義は、明示的にそこに含めない限り (つまり、標準 C++ ライブラリからオブジェクト ファイルを抽出してライブラリに含めない限り)、独自の静的ライブラリには表示されません。静的ライブラリはまったくリンクされておらず、他のライブラリへの未定義の参照があるだけです。スタティック ライブラリは、ライブラリによって提供されるシンボルを定義するオブジェクト ファイルの単なるコレクションです。インライン関数やテンプレートのインスタンス化など、ヘッダーからの定義は、複数の翻訳単位の複数の定義が競合しないように定義されます。コードが実際にインライン化されていない場合、リンク時に重複が無視または削除される「弱い」シンボルが定義されます。

唯一の懸念事項は、実行可能ファイルにリンクされたライブラリが互換性のあるライブラリ定義を使用する必要があることです。ヘッダー ファイルにはかなりの量のコードが存在するため、標準の C++ ライブラリ ヘッダーを含む C++ ヘッダー ファイルは比較的頻繁に変更されます (コードがはるかに少ない C ライブラリ ヘッダーと比較して)。

于 2012-12-31T02:10:36.620 に答える
0

これが実際に問題になることはめったにありません。

ヘッダー ファイルで定義された関数およびインライン テンプレート関数についてstaticは、心配する必要はありません。すべてのコンパイル ユニットが独自のコピーを取得します (たとえば、.aライブラリ内には既に多くの匿名コピーがある場合があります)。これらの定義はエクスポートされないため、これは問題ありません。したがって、リンカーはそれらについて心配する必要はありません。

非静的リンケージで宣言されている関数の場合、問題があるかどうかは、.aライブラリをどのようにリンクするかによって異なります。

ライブラリをビルドするとき、通常は標準 C++ ライブラリにリンクしません。作成されたライブラリには、標準 C++ ライブラリへの未定義の参照が含まれます。これらは、最終的な実行可能バイナリをビルドする前に解決する必要があります。これは通常、最終的なバイナリをデフォルトの方法でリンクするときに自動的に行われます (コンパイラによって異なります)。

標準 C++ ライブラリをスタティック ライブラリにリンクする場合があります。それぞれが別のライブラリ (標準 C++ ライブラリなど) を埋め込んでいる複数の静的ライブラリに対してリンクしている場合、それらの埋め込みライブラリに違いがあると問題が発生することが予想されます。幸いなことに、少なくともgccツールチェーンでは、これはまれな問題です。これは、Microsoft のツールでより頻繁に発生する問題です。

場合によっては、競合する 1 つ以上の静的ライブラリを動的ライブラリにすることで回避できます。このようにして、これらの動的ライブラリのそれぞれが、問題のあるライブラリの独自のコピーを静的にリンクできます。動的ライブラリが問題のあるライブラリからシンボルをエクスポートせず、メモリ レイアウトの非互換性がない限り、通常は問題はありません。

于 2012-12-31T03:54:57.533 に答える
0

はい、標準ライブラリのコードが複製されます。たとえば、 std::string を返したり、メソッドの 1 つでパラメーターとして取得したりすると、問題になる可能性があります。標準ライブラリの実装とユーザーの実装では、レイアウトが異なる場合があります。

于 2012-12-31T02:03:43.933 に答える