Как предотвратить оптимизацию компоновщиком кода запуска?
-
18-09-2019 - |
Вопрос
У меня возникла следующая проблема:Мой проект (C ++-) состоит из нескольких подпроектов.В каждом из них у меня есть несколько файлов с кодом, который я хочу запустить при запуске.Мое решение на данный момент состоит в использовании статических переменных, которые вызывают соответствующий код при инициализации следующим образом:
// Foo.cpp
static TFooRegistry sFooRegistry; // does stuff in constructor.
При создании моего проекта с использованием библиотек DLL для каждого подпроекта все работает нормально, и код выполняется, как ожидалось.Однако при статическом связывании подпроектов компоновщик определяет, что Foo.o не содержит кода, на который когда-либо ссылались извне, и оптимизирует его.Конечно, я мог бы добавить ссылку на sFooRegistry где-нибудь еще, но это утомительно и чревато ошибками.
Какие (соответствующие стандарту) способы решения этой проблемы существуют?
Хорошо, что я могу сделать на mac / gcc и win / visual studio?
Решение
Не существует стандартных способов принудительной инициализации объектов в библиотеках - вам приходится использовать хитрости в зависимости от вашей конкретной платформы (платформ).Разница между DLL и статической библиотекой (по крайней мере, в Windows) заключается в том, что первый содержит код запуска и завершения работы, который выполняется операционной системой, тогда как второй представляет собой просто конкатенацию объектных файлов.
Кроме того, компоновщик не оптимизирует ваш стартовый код - он просто не связывает его, потому что он, по-видимому, никогда не используется.Компоновщики довольно глупые создания - если вы хотите узнать, как они делают то, что они делают, взгляните на книгу Компоновщики и загрузчики.
Другие советы
Какая-то хитрость, но просмотрите.Для системы Win (но не Linux) используйте явный dllexport - в этом случае компоновщик не знает, используется ли этот символ внешним приложением или нет.