2010-12-05 6 views
2

私は静的ライブラリ(lib.a)とそれにリンクするプログラムを持っています。ライブラリには、それを使用する前に常に呼び出されるエントリポイントはありませんが、プログラムの早い段階でコードを実行する必要があります。だから自分のクラスの静的変数を使うと思った。リンカーは静的なlibをリンクするときオブジェクトファイルを省略できますか。

#include <MyClass.h> 
static MyClass myVar; 

MyClassのコンストラクタが私のコードを実行します。私がlib.aをリンクして "nm"を実行しようとすると、myVarがそこにあるという情報が得られます。しかし、自分のプログラムをリンクして "nm"を試してみると、myVarは表示されません。このコードを既存のファイルに入れると、シンボルは最終実行ファイルに表示されます。何故ですか?この場合、リンカはlib.aライブラリからオブジェクトファイルを省略できますか?私は変数が外部から参照されていないことを知っています(それは静的なものではありません)が、独自のコードを実行する必要があります。

場合によっては、古いSunProコンパイラを使用しています。

+1

グローバル変数の初期化に依存するコードを記述するのは悪い考えです。どのようにしてより良いのか。 – ybungalobill

+0

@ybungalobil:役に立つかもしれません。ユニットテストなどです。 (これは、ほとんどのC++ユニットテストフレームワークが自動テスト登録を処理する方法です)。 @トーマス:あなたはどのコンパイラ/プラットフォームを使用していますか? –

+0

@Billy:それは役に立つかもしれませんが、多くても1つのコンポーネントだけがそれに依存しています。さもなければ、あなたは本当に悪いことを得ることができます(初期化順序は未定義です)。また、彼は "古いSunProコンパイラ"を使用していると書いています。 – ybungalobill

答えて

0

リンカのことはかなり標準的ですC++標準を意味し、一般的にはオブザーバーの動作のみ)、それを回避することができます。 GNU ldでは--whole-archiveオプション、私の場合はSunツールの場合は-z allextractです。私のプロジェクトでは実際には期待どおりに動かなかったので、弱い記号のある魔法を使って、私が望むものを実現しました。-z weakextract

1

技術的に言えば、リンカーは、プログラムをコンパイルする際に、そのオブジェクトファイルを強制的に含める必要があります。しかし、これは多くのコンパイラでは、MSVC++などのバグがあります。メインプログラムのどこかに外部参照を追加すると、そのオブジェクトファイルが強制的にインクルードされます。

nmの場合は、静的イニシャライザがインライン展開されている可能性があるため、シンボルが最終バイナリに存在する必要はありません。あなたの静的に副作用(例えばstd::coutステートメントなど)を試して、コンパイラを非難する前に実行されていないことを確認してください:)

+0

私はそれがうまくいかないことを知っています。それがnmで調査を開始した理由です。それは通常動作するはずですが、情報をありがとう、それはC + + /他の標準で定義されているかどうかを知っていいですか、それは他のコンパイラで動作しますか? –

+0

@Tomasz:C++標準では、最終的なバイナリの組み立て方については何も言及していません。 (つまり、スタンダードは静的または動的ライブラリの存在を知らない)これは、標準がマシンニュートラルであるために書かれており、このようなライブラリは多くのアーキテクチャ(特にコードとデータを分離するライブラリ)では不可能であるため、 –

関連する問題