For static TLS vars only visible inside a function, clang will only generate an initializer inside the function body where the variable was declared. However, it is possible for the variable to be indirectly referenced without ever calling the function it was declared in, if a scope referring to the variable gets outlined into a function that is executed on a new thread. Here are two examples that demonstrate this:
#include <thread> #include <iostream> struct Object { int i; Object() : i(3) {} }; int main(void) { static thread_local Object o; std::cout << "[main] o.i = " << o.i << std::endl; std::thread t([] { std::cout << "[new thread] o.i = " << o.i << std::endl; }); t.join(); }
#include <iostream> #include <omp.h> struct Object { int i; Object() : i(3) {} }; int main(void) { static Object o; #pragma omp threadprivate(o) #pragma omp parallel #pragma omp critical std::cout << "[" << omp_get_thread_num() << "] o.i = " << o.i << std::endl; }
In this patch, we generate an initializer in a function for every unique reference to a static TLS var that was declared in a different function.
If you don't care about the iteration order, using pop_back on a vector is faster.