Когда во время выполнения библиотека std полностью инициализируется, чтобы ее можно было использовать, не нарушая код? - PullRequest
0 голосов
/ 05 июня 2018

Я работаю над проектом, который включает код запуска до вызова main.Однако я не знаю об инициализации библиотеки std.

Я знаю, что следующий код вызовет ошибку сегментации.

#include <iostream>

void foo(void) __attribute__((constructor));
void foo() {
  std::cout << "foo" << std::endl;
}

int main() {
  std::cout << "Simple program to throw a segmentation fault" << std::endl;
}

Приведенный выше код можно заставить работать принудительно, инициализируя ostreamбуфер (не уверен, что это точно ostream) с помощью std::ios_base::Init mInitializer;.Это будет означать, что на этом этапе библиотека std не была полностью инициализирована (это мой вывод из приведенного выше примера).

Итак, когда я могу использовать функции std, фактически не нарушая код?Есть ли способ принудительно инициализировать полную библиотеку STD?

1 Ответ

0 голосов
/ 05 июня 2018

Документация для атрибута constructor гласит:

Однако в настоящее время порядок, в котором конструкторы для объектов C ++ со статической продолжительностью хранения и функций украшеныатрибут constructor вызывается не определено.

Это означает, что конструкторы ELF и статические объекты (например, используемые для инициализации std::cout) плохо смешиваются.

Вкл.С другой стороны, std::cout является историческим исключением, поскольку не полагается на конструктор в стандартной библиотеке C ++.В системах ELF конструкторы ELF работают в топологическом порядке.Это означает, что динамический компоновщик просматривает библиотечные зависимости (записи DT_NEEDED) и задерживает инициализацию библиотек до инициализации их зависимостей.

В результате код C ++ может предполагать, что библиотека времени выполнения C ++полностью инициализируется при запуске конструкторов ELF и создании глобальных объектов, определенных приложением.Единственным исключением является библиотека C ++, которая выгружает подпрограммы, используемые самой стандартной стандартной библиотекой C ++ (посредством взаимного расположения символов ELF), и если между библиотеками существуют циклические зависимости, так что нет правильного порядка инициализации.Оба случая не являются общими, и если вы не напишите пользовательский malloc или что-то в этом роде, этого можно избежать при правильном дизайне приложения.

...