0

For example, I have a thread_local variable in my code, but there are a set of functions, which access and modify it. For modularity, I took out them to a different translation unit (correct me if I'm wrong on terminology), by creating a header with their declarations and source file with their definitions.

// fun.h int fun(); 
// fun.cpp #include "fun.h" int fun() { // Modify the thread_local variable here } 
// main.cpp #include "fun.h" thread_local int var = 0; int main() { // Modify the var in the main var = 1; // Modify the var by calling the fun() from fun.h fun(); } 

What to do? How to access it from fun()? Isn't there a contradiction that global variables are common for all the threads of the process, but thread_local is local?

5
  • 1
    Same as any non-thread-local variable or function. You need to declare it in a header so the other files know it exists. Thread-local is irrelevant to this problem. Commented Nov 16, 2021 at 23:19
  • 1
    Global variables are more a trap than anything else. They look like an easy solution to a problem, then later you notice while debugging that every freaking function in the program now could have a hard-to-spot side effect. If a value can be changed at any time by any thing, good luck easily isolating the problem! Commented Nov 16, 2021 at 23:29
  • 1
    @MooingDuck "You need to declare it in a header so the other files know it exists" - more accurately, you just need to declare it as extern in the translation unit that wants to access it. That is commonly done using a header file, but that is not strictly a requirement. Commented Nov 16, 2021 at 23:39
  • Your main.cpp depends on fun.cpp (i.e., it uses something that is defined in fun.cpp.) And now you want fun.cpp to depend on main.cpp. If you do that, you'll be creating a circular dependency. No big deal in a simple exercise, but circular dependencies can lead to huge headaches when they occur in large projects. You should learn to spot them and eliminate them now—maybe save yourself some trouble later in your career. Commented Nov 17, 2021 at 1:35
  • P.S., in this case, maybe the best way to eliminate the circular dependency is also the simplest: recognize that they both belong in the same compilation unit. Get rid of fun.cpp altogether, and move everything into main.cpp. Commented Nov 17, 2021 at 1:38

1 Answer 1

5

The variable var is already global. "Global" refers to the scope of the variable: it means it is declared in the outermost namespace, so its use is not restricted to a particular block, class, or sub-namespace. So a variable can be both global and thread-local without any contradiction.

All you're asking for is how to allow this global, thread-local variable to be accessed by other translation units. Well, one obvious solution is to declare fun as int fun(int& var), so in main.cpp you would call it as fun(var) instead of just fun(). If you do that, you might not need a global variable, and your code will be easier to reason about. But I'm going to assume you have a good reason why you can't do that.

If that's the case, you should provide a declaration of the variable in fun.h:

extern thread_local int var; 

Now every translation unit that includes fun.h is made aware of the existence of a global variable named var, which is of type int and has thread-local storage duration. It is assumed that one translation unit, somewhere in the program, will provide a definition of var, and all other translation units are just referring to that variable. (Since it's a thread-local variable, this single definition creates a set of objects: one per thread.) In your case, that definition, thread_local int var = 0;, is in main.cpp.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.