https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81047

            Bug ID: 81047
           Summary: thread local storage static class members of class
                    type cannot be initialized
           Product: gcc
           Version: 5.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jason.vas.dias at gmail dot com
  Target Milestone: ---

I am not seeing how it is possible to initialize a static TLS structure
member that is of a class type :
<quote><code><pre>
#include <pthread.h>
#include <string>
struct in_tls
{ int a;
  std::string b;
};
bool tls_init=false;
struct A
{ static __thread in_tls _in_tls ;
  void f()
  { _in_tls.a = 1;
  }
  A()
  { if( !tls_init )
    { _in_tls = { 0, std::string() };
      tls_init = true;
    }
  }
};
__thread in_tls A::_in_tls = { 0 };
// = { 0, "" } | 
// = { 0, std::string() } : tried both, same result
void init(void)
{ A::_in_tls.b=std::string();
  tls_init=true;
}
void init(void)  __attribute__((constructor));
int main(int argc, char *const* argv)
{ A a; a.f();
  return 0;
}
</pre></code></quote>

G++ 5.4.0 refuses to accept that 'in_tls.b' is initialized:

$ g++ -std=gnu++11 -I. -D_REENTRANT -pthread -fPIC -pipe -Wall -Wextra \
 -Wno-unused -o /tmp/t /tmp/tTLS.C
/tmp/tTLS.C:20:34: warning: missing initializer for member 'in_tls::b'
[-Wmissing-field-initializers]
 __thread in_tls A::_in_tls = { 0 };
                                  ^
/tmp/tTLS.C:20:34: error: non-local variable 'A::_in_tls' declared '__thread'
needs dynamic initialization
/tmp/tTLS.C:20:17: note: C++11 'thread_local' allows dynamic initialization and
destruction
 __thread in_tls A::_in_tls = { 0 };
                 ^

But I cannot seem to find ANY way to initialize a member like 'b' of a 
static TLS member .

The test code compiles fine (with a warning about uninitialized '_in_tls.b',
(unless its initializer is specified like '{0, std::string()}', then no
warning) - but does succeed, if either of :
1. '__thread' is undefined and redefined as nothing ;
 #undef __thread
 #define __thread
 (not a  workaround!)
OR
2. '_in_tls.b' is made to be not a C++ class object, like 'const char *' -
 (again, not a workaround)
changes are made.

There is no way to put C++ object structure members in TLS and get them
initialized ?

I have tried compiling with '-std=gnu++1'{4,7} with same result.

Is there any special magic I need to do to get the example
std::string '_in_tls.b' initialized so that compiler sees it and 
does not fail with the error?

Incidentally, the error is very confusing - it first claims that it
is an error to attempt to initialize the TLS variable dynamically, and
then issues a 'note:' that C++11 supports dynamic initialization of 
TLS objects - but it doesn't ?

thanks in advance for any advice,
Jason

Reply via email to