我有一个线程本地变量envptr
,还有一个非线程本地变量也叫envptr
。后一个变量仅在单个线程中使用,其运行代码不会看到线程本地变量声明。不同的线程使用线程本地变量,每个线程都不看到,也不需要看到非线程本地变量的声明。
这种情况是否可能并产生定义良好的行为?我在x86上使用linux 32位和64位。
我有一个线程本地变量envptr
,还有一个非线程本地变量也叫envptr
。后一个变量仅在单个线程中使用,其运行代码不会看到线程本地变量声明。不同的线程使用线程本地变量,每个线程都不看到,也不需要看到非线程本地变量的声明。
这种情况是否可能并产生定义良好的行为?我在x86上使用linux 32位和64位。
它们是相同的变量吗?换句话说,它们的链接是什么?
如果它是外部的,那就不是。如果它是内部的,那就没问题,除非两个定义都出现在同一个文件中。
如果没有链接,那就没有问题。
除非我忽略了什么,thread_local
对链接没有影响,因此通常的规则适用(在一个翻译单元中定义变量thread_local
而在另一个翻译单元中未定义违反了一次定义规则)。
然而,我认为标准存在一个错误(§7.1.1/1)。标准规定:“如果在任何变量声明中出现thread_local
,则在该实体的所有声明中都必须存在。”没有明确说明不需要诊断,或者违反此规则是未定义行为,因此编译器必须诊断错误。当然,如果你在命名空间作用域下定义:
thread_local int i;
int i;
如果在另一个地方出现错误,则编译器可能无法诊断错误(我相当确定委员会不想要求这样做)。我的猜测是意图是未定义的行为。
这样做应该可以正常工作并产生正确的行为,因为这两个变量是两个不同的变量。
我强烈建议不要这么做,因为这只会使软件难以维护。无论这种行为是否正确,代码的可读性似乎更重要 - 对于具有截然不同行为的两组数据使用相同的变量名称似乎存在问题。
namespace thread_local
或其他名称空间中。 - Yakk - Adam Nevraumontnamespace virtual
这样的东西怎么样? - Yakk - Adam Nevraumont根据您的描述,似乎它们是两个不同的变量(它们中的任何一个都从未遮盖另一个),在技术层面上这似乎是完全可以的。
尽管如此,我永远不会建议这样做,因为最有可能发生的事情是,在未来的维护中,某人会对其含义感到困惑,并且尝试理解代码会导致更多问题。
envptr
如何使用__thread
进行修饰,而另一个则不是?我唯一能想象到的方式是在两个不同文件中使用非外部变量..如果是这样的话,那么它似乎可以在这种情况下简单地回答。 - user166390Env *getEnv();
。每个.cpp
文件都有不同的定义。使用TLS版本的线程运行在与使用非TLS变量的主线程加载到同一进程中的.so
文件中的代码上(这是由REPL shell使用的LLVM JIT编译器)。 - Johannes Schaub - litb