Rules and Restrictions on Using TLS (Windows)

  1. __thread can only be used for data declarations and definitions.
    /* Declaration of an integer thread local variable and its initialization: */
    
      __thread int tlsVar1 = 1;
    
      static __thread int tlsVar2 = 100;
  2. The __thread attribute cannot be used on function declarations or definitions.
    /* Declaration of a thread local function: */
    
      __thread void func();                  // Error
    
    
  3. The __thread attribute can be specified only on data items with static storage duration.
    /* Declaration of an integer thread local variable and its initialization: */
    
      __thread int tlsVar1 = 1;
    
      static __thread int tlsVar2 = 100;
    
  4. The __thread attribute cannot be used to declare automatic data objects.
    /* Declaration of a thread local variable with an
       automatic storage duration */
    
      void
      func1()
      {
         __thread int tlsVar;                 // Error
      }
    
      int
      func2( __thread int tlsVar )           // Error
      {
            return tlsVar;
      }
    
      auto __thread float tlsVar;            // Error
    
  5. The __thread attribute must be used for the declaration and definition of a thread local object. This is true whether or not the declaration and definition occur in the same file.
    /* Mismatch in declaring and defining a thread local object either in the
       same file or in separate files: */
    
      extern int tlsVar;             // This is not allowed since the declaration
      __thread int tlsVar;           // and the definition differ.
    
  6. Because C++ objects with constructors and destructors, as well as objects that use initialization semantics, can be allocated as thread local, an associated initialization routine must be called to initialize the object.
    /* Initializing the thread local object by the class constructor: */
    
      class tlsClass
      {
           public:
              tlsClass() { x = 1; } ;
              ~tlsClass();
    
           private:
              int x;
      }
    
      __thread tlsClass tlsObject;
      extern int func();
      __thread int y = func();
    
  7. The __thread attribute cannot be used as a type modifier. If it is used as a type modifier, it will have no effect on the type.
  8. The __thread attribute cannot be used by the C++ classes or enumerated types. However, the C++ class objects or variables of an enumerated type can be initiated with the __thread attribute.
    /* Declaring a C++ class with a thread attribute: */
    
      __thread class C              // Error
      {
          . . .
      };
      C CObject;
    
    /* Declaring a C++ class object with a thread attribute.
       Because the declaration of C++ objects that use the thread
       attribute is permitted, these two examples are semantically
       equivalent:  */
    
      __thread class B
      {
         . . .
      } BObject;
    
      class B
      {
         . . .
      }
      __thread B BObject;
    
  9. The address of a thread local object is not considered constant, and any expression involving such an address is not considered a constant expression. Therefore, the address of a thread local variable cannot be used as an initializer in C.
    /* Initializing a pointer by the address of the thread local variable: */
    
      __thread int tlsVar;
      int *p = &tlsVar;                    // C Error, NOT a C++ error
    
  10. Thread local data cannot be imported or exported.
      extern __thread int _Import i:   /* error */
    
  11. A DLL that contains static TLS data cannot be dynamically loaded with the LoadLibrary system call. In Windows NT, the LoadLibrary call will succeed but you will trap in the DLL when you try to access the _thread data.

Statically declared __thread data objects can be used only in statically loaded files. This fact makes it unreliable to use TLS in a DLL, unless you know that the DLL (or anything statically linked to it) will never be loaded dynamically. In particular, do not attempt to use __thread data objects in DLLs that will be dynamically loaded through the LoadLibrary API. This restriction does not apply to dynamically loaded DLLs that use the thread-local-storage APIs.



Multithreaded Applications
Thread Local Storage