Статический класс thread_local уничтожается по неверному адресу при выходе из программы - PullRequest
3 голосов
/ 11 октября 2019

У меня проблема с уничтожением статического объекта thread_local.

#include <iostream>
#include <thread>

struct UsesLoc {
    UsesLoc() {
        loc.counter++;
    }

    struct Loc {
        Loc() {
            std::cout << "I am at   " << this << " and counter is " << counter << std::endl;
        }
        ~Loc() {
            std::cout << "I was at  " << this << " and counter is " << counter << std::endl;
        }

        int counter = 0;
    };

    static thread_local Loc loc;
};

thread_local UsesLoc::Loc UsesLoc::loc;

int main()
{
    {
        UsesLoc usesloc;
        std::cout << "loc is at " << &UsesLoc::loc << " and counter is " << UsesLoc::loc.counter << std::endl;
    }
    return 0;
}

Как и ожидалось, при компиляции и запуске на https://coliru.stacked -crooked.com / a / e8bcfdaffa6a6da7 обнаруживаетсячто объект thread_local всегда находится в одном и том же месте, а значения счетчика равны (0,1,1):

I am at   0x7f9dc817673c and counter is 0
loc is at 0x7f9dc817673c and counter is 1
I was at  0x7f9dc817673c and counter is 1

И наоборот, когда я локально компилирую с MinGW и запускаю, я получаю, например,

I am at   0x507874 and counter is 0
loc is at 0x507874 and counter is 1
I was at  0x7efdd000 and counter is 2686552

Очевидно, что неинициализированный объект в другом месте памяти уничтожается.

Наблюдал ли я за чем-то недетерминированным? Как я могу убедиться, что правильный объект уничтожен?

1 Ответ

0 голосов
/ 13 октября 2019

Получив подсказку от Теда Люнгмо о том, что это может быть ошибкой компилятора, я провел небольшое исследование, и, похоже, это действительно проблема, о которой уже сообщалось ранее:

При этом код является правильным, а указатель на разрушаемый объект указывает натот же объект, который был создан ранее при использовании стандартного компилятора.

...