First of all, sorry in advance for submitting a bug with no way to reproduce it but I unfortunately already spent several hours on this and I simply can't manage to make this fail in a simple example. In spite of this it seems like this could be a compiler problem and not something in my code so I'd like to report it and let you decide whether it's worth looking into.
Anyhow, the problem is that the compiler seems to do something strange with the code which looks like this: class UTF8String { private: // we use this cache to speed up some common operations on UTF-8 strings struct CacheElement { const UTF8String *str; // the key of the cache int posInChars, posInBytes, len; }; struct Cache { CacheElement cached[8]; int lastUsed; }; static Cache& GetCache() { static Cache s_cache; return s_cache; } // find or allocate one of GetCache().cached elements for this object CacheElement *GetCacheElement() const { ... } public: size_t length() const { CacheElement * const c = GetCacheElement(); if ( cache->len == npos ) cache->len = ... compute ...; return cache->len; } }; Everything works perfectly fine with -O0 and with -O2 in simple examples. However as soon as the code becomes a bit more complicated, sometimes GetCacheElement() in length() returns bogus values, i.e. pointers to the elements which are not in cached array at all (according to its printout, using a special function in the program as gdb seems to be very confused by __thread variables). I suspected a bug in my GetCacheElement(), of course, but it's pretty trivial (linear search in the array basically...) and seems to be correct and, moreover, everything works fine as long as -O2 is not used _or_ the Cache variable is made class static and accessed directly instead of in the above way. The real code can be found at http://svn.wxwidgets.org/viewvc/wx/wxWidgets/trunk/include/wx/string.h?revision=55501&view=markup but needs to be modified by disabling workaround found near comment containing "g++ 4.1.2" string to see the problem. Basically it's enough to do "configure && make && cd tests && make && ./test" to see that it works with -O0 (or with the workaround) and fails in mysterious ways with -O2. Sorry once again for not being able to provide a simpler test case. And all this happens on an amd64 Debian stable machine with (Debian) g++ 4.1.2 in single threaded test code. -- Summary: Incorrect access to static __thread variables inside static member functions Product: gcc Version: 4.1.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: vz-gcc at zeitlins dot org GCC host triplet: x86_64-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37402