Ответ 1
Стандарт ничего не говорит о том, какой поток должен выполнять такую инициализацию. Это требует только определенных заказов и гарантий:
3.6.2 Инициализация нелокальных переменных [basic.start.init]
2. Статическая инициализация должна выполняться до начала любой динамической инициализации. [...] Переменные с упорядоченной инициализацией, определенные в одной единице перевода, должны быть инициализированы в порядке их определений в блоке перевода. [...] Если программа запускает поток, последующая инициализация переменной не зависит от инициализации переменной, определенной в другой единицы перевода. В противном случае инициализация переменной неопределенно секвенирована относительно инициализации переменной, определенной в другой единицы перевода.
4. Определяется реализацией, выполняется ли динамическая инициализация нелокальной переменной со статической продолжительностью хранения до первого оператора main. Если инициализация отложена до некоторого момента времени после первого утверждения main, это должно произойти до первого odr-использования любой функции или переменной, определенной в той же самой единицы перевода, что и инициализированная переменная.
5. Определяется реализацией, выполняется ли динамическая инициализация нелокальной переменной со статикой или длительностью хранения потоков до первого утверждения начальной функции потока. Если инициализация отложена до некоторого момента времени после первого утверждения исходной функции потока, она должна произойти до первого использования odr любой переменной с длительностью хранения потока, определенной в той же самой единицы перевода, что и инициализированная переменная.
Однако большинство реализаций это сделают - инициализация статических нелокальных переменных будет выполняться в том же потоке, который вызывает main()
. Пример из Visual С++ 11:
#include <iostream>
#include <thread>
using namespace std;
struct Cx
{
public:
Cx()
{
cout<<"Cx: "<<std::this_thread::get_id()<<endl;
}
};
static Cx c;
int main()
{
cout<<"Main: "<<std::this_thread::get_id()<<endl;
return 0;
}
Вывод:
Cx: 5820
Main: 5820
После установки точки останова внутри Cx::Cx()
: