8

I have a thread local variable envptr and variable that is not thread-local also called envptr. The latter variable is only used in a single thread whose running code does not see the thread-local variable declaration. The thread-local variable is used by different threads, each of which do not see nor need to see the declaration of the non-thread-local variable.

Is this scenario possible and produces defined behavior? I am using linux 32bit and 64bit on x86.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • Have example code of how one `envptr` would be decorated with `__thread` (?), but another not? The only way I can imagine this is non-externs in two different files .. and if so, then it seems like it might be answerable simply in that context. –  Jan 23 '13 at 18:13
  • 1
    @pst yes, that is how it is done. they are declared in cpp files and a function `Env *getEnv();` is provided in a header. Each `.cpp` file defines it differently. The threads that use the TLS version run on code from an `.so` file loaded into the same process as the main thread that uses the non-TLS variable (which is a LLVM JIT compiler used by a REPl shell). – Johannes Schaub - litb Jan 23 '13 at 18:16
  • I have voted to close because I think it has a really simple solution: I will just use a different name for the .cpp file linked to the DLL and for the .cpp file linked to the main executable. EDIT: This would limit the applicability of the .so files, so I would like to still try other approaches. – Johannes Schaub - litb Jan 23 '13 at 18:26

3 Answers3

4

Are they the same variable, or not? In other words, what is their linkage?

If it is external, then no. If it is internal, then it's OK unless the two definitions both occur in the same file.

If there is no linkage, then there is no problem.

Unless I've overlooked something, thread_local has no impact on linkage, so the usual rules apply (and defining the variable thread_local in one translation unit, and not in another, is a violation of the one-definition rule).

I think there's a bug in the standard here, however. The standard (§7.1.1/1) says that "If thread_local appears in any declaration of a variable it shall be present in all declarations of that entity." There's no explicit statement that a diagnostic is not required, or that violation of this rule is undefined behavior, so a compiler is required to diagnose the error. Except that, of course, if you define at namespace scope:

thread_local int i;

in one translation unit, and:

int i;

in another, then the compiler probably can't diagnose the error (and I'm fairly sure the committee didn't want to require it). My guess is that the intent here is undefined behavior.

Philip Conrad
  • 1,451
  • 1
  • 13
  • 22
James Kanze
  • 150,581
  • 18
  • 184
  • 329
3

This should work, and produce correct behavior, as the variables are two distinct variables.

I would strongly recommend not doing this, as it will just make the software less maintainable. Whether or not this behavior is correct seems less important as how understandable the code will be - using the same variable name for two sets of data with vastly different behavior seems problematic.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • @Yakk The author was using "OK" (which I put in quotes) to refer to question: "Is this scenario possible and produces defined behavior?" –  Jan 23 '13 at 18:09
  • I agree that "it is possible and produces defined behavior". :) But I would strongly advise avoiding having global (and thread-local) variables named the same as local variables -- I would suggest picking a naming scheme. Or even just, by convention, sticking it into a `namespace thread_local` or whatever. – Yakk - Adam Nevraumont Jan 23 '13 at 18:21
  • @Yakk ahh yes I will just name it differently! if you post it as an answer I will accept it! – Johannes Schaub - litb Jan 23 '13 at 18:24
  • 1
    Whether it is two distinct variables or not depends on the linkage. If the linkage is external, they are the same variable. (I'll second @Yakk's suggestion of putting them in different namespaces. Although the name `thread_local` won't work for the namespace name.) – James Kanze Jan 23 '13 at 18:30
  • @JamesKanze Laugh, that is true. :) So, how about something like `namespace virtual`? – Yakk - Adam Nevraumont Jan 23 '13 at 19:53
3

From your description it sounds like they're two distinct variables (neither one ever shadows the other) in which case it seems prefectly ok from a technical standpoint.

That said I would never suggest doing this because the most likely thing to happen is that someone will get confused about the meaning in future maintenance and will cause more problems trying to understand the code.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • 1
    Whether they are two distinct variables or not depends on the linkage of the name (which isn't influenced by `thread_local`). – James Kanze Jan 23 '13 at 18:28