Как предотвратить компоновщик от оптимизации кода запуска?

У меня следующая проблема: Мой (C ++ -) проект состоит из нескольких подпроектов. В каждом из них есть несколько файлов с кодом, который я хочу запустить при запуске. Мое решение до сих пор состоит в том, чтобы использовать статические переменные, которые вызывают соответствующий код при инициализации следующим образом:

// Foo.cpp

static TFooRegistry sFooRegistry;   // does stuff in constructor.

При сборке моего проекта с использованием dll для каждого подпроекта все работает нормально, и код выполняется должным образом. Однако при статическом связывании подпроектов компоновщик определяет, что Foo.o не содержит кода, на который когда-либо ссылались извне, и оптимизирует его. Конечно, я мог бы добавить ссылку на sFooRegistry где-нибудь еще, но это утомительно и подвержено ошибкам.

Какие (стандартные совместимые) способы решения этой проблемы существуют?

Хорошо, что я могу сделать на Mac / GCC и Win / Visual Studio?

Ответы на вопрос(2)

Решение Вопроса

Не существует стандартных совместимых способов принудительной инициализации объектов в библиотеках - вы должны использовать приемы в зависимости от вашей конкретной платформы (платформ). Разница между DLL и статической библиотекой (по крайней мере, в Windows) состоит в том, что первая имеет код запуска и завершения работы, который выполняется ОС, тогда как последняя представляет собой просто конкатенацию объектных файлов.

Кроме того, компоновщик не оптимизирует ваш стартовый код - он просто не связывает его, потому что он, очевидно, никогда не используется. Линкеры - довольно глупые звери - если вы хотите узнать, как они делают то, что делают, взгляните на книгуЛинкеры & Погрузчики.

 anon19 авг. 2009 г., 17:57
Там нет никакой гарантии, что будет связан либо.
 Tobias19 авг. 2009 г., 17:44
Doh! Уважаемый Бьярне: Почему?
 AProgrammer19 авг. 2009 г., 20:50
@Tobias, вы можетет. В C инициализаторы для объектов, имеющих статическую длительность хранения, должны быть константными выражениями (6.7.8 / 4).
 anon19 авг. 2009 г., 17:48
C ++ был разработан для работы с существующими компоновщиками (см. Stroustrup 'с D &Электронная книга), которая не имела / не имела понятия конструкторов.
 Tobias19 авг. 2009 г., 18:00
Конечно, но я все еще неНе понимаю, что вы думаете о конструкторах. Так же 'Зачем' Вот :)
 Tobias19 авг. 2009 г., 17:53
Ну, вы можете сделать то же самое в C: int sRegisterFoo () {...}; static int sFooRegistry = sRegisterFoo ();
 Tobias19 авг. 2009 г., 17:48
Какие'Разница между компоновщиком, оптимизирующим код и не связывающим его? Я думал, что это просто два имени для одного и того же.
 Martin York19 авг. 2009 г., 23:56
@AProgrammer: компоновщик выходит за рамки языка. Язык C ++ определяет только то, что делает компилятор.

Какой-то трюк, но просмотрите его. Для системы Win (но не для Linux) используйте явный dllexport - в этом случае linker doen 't знает, используется ли этот символ внешним приложением или нет.

Ваш ответ на вопрос