我在未初始化的阅读中发现了 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 结果来看,链接器似乎不尊重目标文件顺序和静态初始化。
我有两个问题。首先,如何强制 Apple 的链接器尊重目标文件的顺序?其次,我如何强制 GNU 的链接器尊重目标文件的顺序?
我们不能使用链接器脚本。GCC 的人特别告诉人们不要使用它们。另外,我不确定 Apple 平台上的格式。
对于它的价值,这是一个后备,以防万一init_priority
不可用。不幸的是,它在许多平台上都不可用。只有现代 GNU 链接器拥有它,而 Apple 完全没有它。
(我们的测试可以追溯到很长一段时间,从带有 GCC 3.2 的 Fedora 1 到 Windows 2000)。