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

К>>- выполнили деструкторы SS-объектов, инициализированных по требованию

К>>- выполнили деструкторы SS-объектов

AG>Последнее и предпоследнее не может вперемешку выполнятся?


Технически, там заводится стек экзит-функций. Каждый объект с нетривиальным деструктором при создании (по завершении конструктора, если тот нетривиальный) добавляет свою функцию в atexit().
Если один объект из своего конструктора или из инициализирующей функции создал другой статический объект, тот добавится вперёд него и, соответственно, будет разрушен позже.

К>>первое обращение к TLS провоцирует инициализацию всех TLS-объектов


AG>А в MSVC сразу при старте потока (из TLS Callback). Это implementation-defined, или кто-то нарушает?


Implementation-defined.
Более того, и статические, и потоковые переменные (нелокальные) должны быть инициализированы до первого использования.
А будет это до входа в main или нет, — можно делать и так, и этак, и даже вперемешку!

3.6.2 Initialization of non-local variables [basic.start.init]

4
It is implementation-defined whether the dynamic initialization of a non-local variable with static storage
duration is done before the first statement of main. If the initialization is deferred to some point in time
after the first statement of main, it shall occur before the first odr-use (3.2) of any function or variable
defined in the same translation unit as the variable to be initialized.
[ Example:

// - File 1 -
#include "a.h"
#include "b.h"
B b;
A::A(){
b.Use();
}
// - File 2 -
#include "a.h"
A a;
// - File 3 -
#include "a.h"
#include "b.h"
extern A a;
extern B b;
int main() {
a.Use();
b.Use();
}

It is implementation-defined whether either a or b is initialized before main is entered or whether the
initializations are delayed until a is first odr-used in main. In particular, if a is initialized before main is
entered, it is not guaranteed that b will be initialized before it is odr-used by the initialization of a, that is,
before A::A is called. If, however, a is initialized at some point after the first statement of main, b will be
initialized prior to its use in A::A. — end example ]

5
It is implementation-defined whether the dynamic initialization of a non-local variable with static or thread
storage duration is done before the first statement of the initial function of the thread. If the initialization
is deferred to some point in time after the first statement of the initial function of the thread, it shall occur
before the first odr-use (3.2) of any variable with thread storage duration defined in the same translation
unit as the variable to be initialized.


Технически проще и экономнее создать одну мега-функцию конструирования всех статических переменных в единице трансляции, и парную к ней мега-функцию деструирования, и дёргать их до и после main, соответственно, — чем заниматься тем же самым с каждой переменной индивидуально. Но не возбраняется и индивидуально.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.