Ответ здесьдемонстрирует, что __attribute__((конструктор)) не вызывается послестатической инициализации, он вызывается в порядке объявления.
Тогда какова его цель, если не гарантируется, что он будет вызван при инициализации всех данных? Мы могли бы также иметь наш ((конструктор)) код в конструкторе Foo.
Я ищу способ иметь в разделяемой библиотеке код, который будет выполняться после инициализации всех статических данных и вызова статических конструкторов. Я видел, как люди рекомендовали __attribute__((constructor)) в качестве замены DllMain; как мы видим, это неправильно, потому что некоторые статические данные могут быть еще не инициализированы.
Конечно, в одном файле (единице компиляции) можно было бы организовать статику. Но в типичной программе много файлов.Есть ли способ гарантировать, что ((конструктор)) в одном файле будет определенно вызываться после того, как все остальные статические элементы в общей библиотеке будут инициализированы?
Если я помещу файл со статической инициализацией (конструктор, объект и т.д.) в конец командной строки gcc:
g++ -shared -fPIC source1.o source2.o MyLastInitChance.o
гарантированно ли, что статические конструкторы этого файла будут вызываться последними? Я экспериментировал, и когда я меняю порядок исходных файлов, порядок printfs меняется; но указан ли он где-нибудь и гарантированно ли он будет одинаковым для систем/компьютеров компиляции?
Например, цитата:
Во время компоновки драйвер gcc помещает crtbegin.o непосредственно перед всеми перемещаемые файлы и crtend.o сразу после перемещаемые файлы. ©
Насколько я понимаю, приведенная выше цитата подразумевает, что порядок файлов .o, передаваемых компоновщику, определяет порядок статической инициализации. Я прав?
Другое интересное возможное решение, возможно, заключается в написании подключаемого модуля GCC, который корректирует статическую инициализацию (например, добавляет код в раздел .ctors и т. д.). Но это всего лишь идея, которую, возможно, кто-то сможет расширить.
Еще одно возможное решение представленоздесь. Короче говоря, внешний инструмент пост-сборки можно использовать для изменения порядка записей .ctors в исполняемом файле (библиотеке). Но я не эксперт в формате ELF; Интересно, возможно ли это и достаточно ли легко настроить файлы .so таким образом.
Меня интересует решение конкретной проблемы или доказательство того, что ее решить невозможно (по крайней мере, почему приведенные выше решения не будут работать).