Я ловлю находку Вальгринда в неинициализированном прочтении. Я точно знаю, откуда он взялся — его пустое 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
отображается во второй раз, чтобы обеспечить возможность обнаружения всех символов для тестового объекта, поскольку они являются однопроходными компоновщиками.
Результаты Valgrind для OS X и Linux показывают, что компоновщики не соблюдают порядок объектных файлов и статическую инициализацию.
У меня два вопроса. Во-первых, как заставить компоновщик Apple соблюдать порядок объектных файлов? Во-вторых, как заставить компоновщик GNU соблюдать порядок объектных файлов?
Мы не можем использовать скрипты компоновщика. Люди GCC специально говорят людям не использовать их. Кроме того, я не уверен в формате на платформах Apple.
Для чего это стоит, это запасной вариант в случае init_priority
не доступен. К сожалению, его нет на многих платформах. Только у современных GNU-линкеров это есть, а у Apple его нет полностью.
(Наше тестирование проходит довольно долгий путь, от Fedora 1 с GCC 3.2 до Windows 2000).
Задача ещё не решена.
Других решений пока нет …