Что такое "static initialization order fiasco" (SIOF)?
Это фейл, который случается, когда переменные с динамической инициализацией используют для своей инициализации другие переменные с динамической инициализацией. В этом примере глобальная переменная g_b
использует для инициализации значение глобальной переменной g_f
из другой единицы трасляции, которая может быть, а может и не быть инициализирована к этому моменту, так как порядок динамической инициализации переменных в разных единицах трансляции не определен. На практике может получаться, что код с такой проблемой то работает, а то нет, в зависимости от особенностей компилятора, порядка сборки / линковки.
// Foo.hpp
#include <string>
struct foo{ ::std::string value; };
foo & Get_GlobalFoo(void);
// Foo.cpp
#include "foo.hpp"
#include <string>
static foo g_f{::std::string{"whatever"}};
foo & Get_GlobalFoo(void) { return g_f; }
// Bar.hpp
#include <string>
struct bar{ ::std::string value; };
bar & Get_GlobalBar(void);
// Bar.cpp
#include "foo.hpp"
#include "bar.hpp"
static bar g_b{Get_GlobalFoo().value};
bar & Get_GlobalBar(void) { return g_b; }
// Main.cpp
#include "bar.hpp"
#include <iostream>
int main()
{
::std::cout << Get_GlobalBar().value << ::std::endl;
return 0;
}
Защититься от такой проблемы достаточно просто - достаточно никогда не прибегать к динамической инициализации (и заодно и к последующему разрушению). Проще говоря, все статические переменные должны быть constexpr
и / или тривиально инициализироваться нулями, а также иметь тривиальный деструктор.
Несмотря на страшное название, вещь это очень простая. Представим, что у нас есть две статических переменных в разных исходных файлах, причем одна из них при инициализации каким-то образом ссылается на другую, например, вызывает метод класса. Поскольку порядок инициализации статических переменных не определен, существует 50%-ая вероятность, что зависимая переменная будет инициализирована первой, и при этом обратится к еще неинициализированной второй переменной. Программа соответственно аварийно завершится, не выполнив ни единого оператора. Вот эта ситуация и называется SIOF.
Поэтому классовые переменные лучше вообще не делать статическими, или хотя бы следить, чтобы таких зависимостей не возникало.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Нужно нарисовать пирамиду, содержащую n строкЕсли n будет, например, 4, то пирамида должна выглядеть следующим образом:
Хочу спросить, как получить список игроков их ip, на localhost и как отслеживать их подключение