初期化されていない読み取りで Valgrind の結果をキャッチしています。私はそれがどこから来たのかを正確に知っています -ストレージクラスを持つファイルでstd::string
宣言された空のものです。cpp
static
のストレージ割り当てを持つオブジェクト ファイルはstd::string
、静的アーカイブの最初にリストされます。
# string of interest is located in a.o
LIBOBJS := a.o b.o c.o ... x.o y.o z.o
library.a: $(LIBOBJS)
$(AR) $(ARFLAGS) $@ $(LIBOBJS)
$(RANLIB) $@
さらに、リンクのレシピを次のように変更しました (ばかげているように見えます)。
program.exe: library.a $(TESTOBJS)
$(CXX) $(CXXFLAGS) -o $@ ./library.a $(TESTOBJS) ./library.a -pthread
上記は、静的初期化子が実行される最初の初期化子であることを確認するためlibrary.a
に最初にリストされています。これらはシングルパスリンカーであるため、テストオブジェクトのすべてのシンボルを確実に見つけることができるように、もう一度リストされます。std::string
library.a
OS X と Linux の両方での Valgrind の結果から、リンカーはオブジェクト ファイルの順序と静的初期化を尊重していないようです。
2 つの質問があります。まず、Apple のリンカにオブジェクト ファイルの順序を強制するにはどうすればよいですか? 次に、GNU のリンカにオブジェクト ファイルの順序を強制するにはどうすればよいですか?
リンカー スクリプトは使用できません。GCC の人々は、それらを使用しないように明確に伝えています。さらに、Apple プラットフォームでのフォーマットもよくわかりません。
これは、init_priority
が利用できない場合のフォールバックです。残念ながら、多くのプラットフォームでは利用できません。最新の GNU リンカーだけがそれを持っており、Apple には完全に欠けています。
(私たちのテストは、GCC 3.2 を使用した Fedora 1 から Windows 2000 まで、かなり遡ります)。