@Quark_Hell
C++ программист

Почему статическая переменная инициализируется дважды?

Здравствуйте. Я работаю со статической библиотекой, в которой находится точка входа. Соответственно, дабы этой библиотеке передать свои данные, я в глобальном пространстве проекта создаю переменную:
MyScript* script = dynamic_cast<MyScript*>(new MyScript(Register::UserScriptType::Component));

После вызывается конструктор, которые добавляет указатель на мой скрипт в общий контейнер:
bool Register::Registry::RegisterActorWithComponent(Register::UserScript* script, std::string objectName) {
	//Check if script cannot be converted
	if (dynamic_cast<Register::UserScript*>(script) == nullptr)
		return false;
	
	//Later Host will call all UserScript functions
	_userScripts.push_back(script);
	return RegisterActor(objectName);
}

Всё это происходит до main функции.
Однако когда программа заходит в неё, контейнер вдруг оказывается пустым. И выглядит это так, как будто где-то этот контейнер заново инициализируется, за счёт чего теряет данные.

Вот мой класс регистратора юзер скриптов, который находится в статической библиотеке:
namespace Register {
	class UserScript;

	class Registry
	{
		friend class Core::Host;

	public:
		static std::vector<Register::UserScript*> _userScripts;

	public:
		~Registry();

		static bool RegisterActorWithComponent(Register::UserScript* script, std::string objectName = "Undefined");
		static bool RegisterActor(std::string objectName = "Undefined");
		
	private:
		static std::unique_ptr<Register::Registry> MakeRegistry();
		Registry();

		void RegistryStart();
		void RegistryLoop();
	};
}


Для сборки и библиотеки и екзешника используется CMake

Дайте знать, если вам понадобиться больше информации. Заранее спасибо.
  • Вопрос задан
  • 144 просмотра
Решения вопроса 1
@MarkusD Куратор тега C++
все время мелю чепуху :)
Первое, с чего стоит начать ответ: Порядок инициализации глобальных данных программы стандартом не определен.
Поэтому нельзя говорить о том, какие конструкторы после каких вызываются. Сейчас это так, а завтра поменяется.
Описанный у тебя случай - это Static Initialization Order Fiasco.

Сценариев описания происходящего у тебя будет много. Детали зависят от выбранного у тебя транслятора, его версии и стандарта языка.

Как с этим справляться? Отец-основатель уже очень давно все рассказал.
Нужно просто воспользоваться стандартом языка. Тем, что стандарт предписывает инициализировать статические данные внутри функции при первом ее вызове.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы