Re[5]: Поясните за деструкторы thread_local (3.6.3/1)
От: Кодт Россия  
Дата: 21.03.17 10:52
Оценка:
Здравствуйте, vdimas, Вы писали:

К>>Если один объект из своего конструктора или из инициализирующей функции создал другой статический объект, тот добавится вперёд него

V>Сам добавиться?

Ну как сам.
Рядом с каждым статическим объектом есть две незримых функции — первая его инициализирует и добавляет в atexit вторую, а вторая разрушает.
Если очень грубо, то
// static X x (a,b,c);

using X_Data = aligned_storage<sizeof(X), alignof(X)>::type;

static X_Data x_data;
static bool x_created = false;

static X& x = (X&)x_data;

void touch_x() {
  if (!x_created) {  // сейчас не будем морочить себе голову вопросами реентера и многопоточности
    new (&x) X(a,b,c);
    atexit(kill_x);
    x_created = true;
  }
}
void kill_x() {
  if (x_created)
    x.~X();
}

X& take_x() { touch_x(); return x; }

//////// зависимый от него static Y y(x);

void touch_y() {
  if (!y_created) {
    new (&y) Y(take_x()); // в рамках take_x -> touch_x мы добавим kill_x
    atexit(kill_y);       // вперёд добавления kill_y
    y_created = true;
  }
}


Для локальных объектов (синглетоны Мейерса) всё это добро существует физически.
Для нелокальных — если компилятор предпочитает пакетную инициализацию всех переменных в единице трансляции, то он может сократить слагаемые — родить две такие функции touch_everything, kill_everything на всю единицу.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.