Информация об изменениях

Сообщение Re: Поясните за деструкторы thread_local (3.6.3/1) от 15.03.2017 17:40

Изменено 15.03.2017 18:05 Кодт

Re: Поясните за деструкторы thread_local (3.6.3/1)
Здравствуйте, Alexander G, Вы писали:

AG>

AG>The completions
AG>of the destructors for all initialized objects with thread storage duration within that thread are sequenced
AG>before the initiation of the destructors of any object with static storage duration.


Тут, скорее, речь вот о чём.
Главный поток (который main() ± конструкторы-деструкторы-exit-функции) — это тоже поток.
И его завершение происходит в таком порядке:
— вышли из main
— выполнили деструкторы TLS-объектов
— выполнили деструкторы SS-объектов, инициализированных по требованию
— выполнили деструкторы SS-объектов

http://ideone.com/B8XhTJ
struct X {
    const char* name;
    X(const char* name) : name(name) { cout << name << " : ctor" << endl; }
    ~X() { cout << name << " : dtor" << endl; }
};

thread_local X a("a");
X b("b");

int main() {
    cout << "start!" << endl;
    static X c("c");
    cout << "test " << a.name << endl; // первое обращение к объекту, чтобы создать его
    static X d("d");
    cout << "finish!" << endl;
}

b : ctor
start!
c : ctor
a : ctor
test a
d : ctor
finish!
a : dtor  -- произошёл обгон!
d : dtor
c : dtor
b : dtor
Re: Поясните за деструкторы thread_local (3.6.3/1)
Здравствуйте, Alexander G, Вы писали:

AG>

AG>The completions
AG>of the destructors for all initialized objects with thread storage duration within that thread are sequenced
AG>before the initiation of the destructors of any object with static storage duration.


Тут, скорее, речь вот о чём.
Главный поток (который main() ± конструкторы-деструкторы-exit-функции) — это тоже поток.
И его завершение происходит в таком порядке:
— вышли из main
— выполнили деструкторы TLS-объектов
— выполнили деструкторы SS-объектов, инициализированных по требованию
— выполнили деструкторы SS-объектов

http://ideone.com/B8XhTJ
#include <iostream>
using namespace std;

int g_tab = 1;
struct X {
    int tab;
    const char* name;
    X(const char* name) : name(name), tab(g_tab++) {
        cout << string(tab, '\t') << name << " : ctor" << endl;
    }
    ~X() {
        cout << string(tab, '\t') << name << " : dtor" << endl; }
};

X g1("g1");
thread_local X t1("t1");
thread_local X t2("t2");
X g2("g2");

int main() {
    cout << "start!" << endl;
    static X s1("s1");
    cout << "test " << t1.name << endl;  // первое обращение к TLS провоцирует инициализацию всех TLS-объектов
    static X s2("s2");
    cout << "finish!" << endl;
}

    g1 : ctor
        g2 : ctor
start!
            s1 : ctor
                t1 : ctor
                    t2 : ctor
test t1
                        s2 : ctor
finish!
                    t2 : dtor
                t1 : dtor
                        s2 : dtor
            s1 : dtor
        g2 : dtor
    g1 : dtor

Вот здесь таится опасность: нарушение порядка.