【问题标题】:Is it OK to have a thread-local variable with the same name as a non-thread-local variable?有一个与非线程局部变量同名的线程局部变量是否可以?
【发布时间】:2013-01-07 07:37:27
【问题描述】:

我有一个线程局部变量envptr 和不是线程局部的变量也称为envptr。后一个变量仅在运行代码看不到线程局部变量声明的单个线程中使用。线程局部变量被不同的线程使用,每个线程看不到也不需要看到非线程局部变量的声明。

这种情况是否可能并产生已定义的行为?我在 x86 上使用 linux 32 位和 64 位。

【问题讨论】:

  • 有一个envptr 将如何用__thread 装饰的示例代码(?),但另一个没有?我能想象到的唯一方法是两个不同文件中的非外部文件.. 如果是这样,那么在这种情况下似乎可以简单地回答。
  • @pst 是的,就是这样做的。它们在 cpp 文件中声明,并且在标头中提供了函数 Env *getEnv();。每个.cpp 文件对它的定义都不同。使用 TLS 版本的线程运行在来自 .so 文件的代码上,该文件加载到与使用非 TLS 变量(这是 REPl shell 使用的 LLVM JIT 编译器)的主线程相同的进程中。
  • 我投票关闭,因为我认为它有一个非常简单的解决方案:我将为链接到 DLL 的 .cpp 文件和链接到主可执行文件的 .cpp 文件使用不同的名称.编辑:这会限制 .so 文件的适用性,所以我还是想尝试其他方法。

标签: c++ c thread-local


【解决方案1】:

它们是同一个变量吗?换句话说,什么是 他们的linkage

如果是外部的,那么没有。如果它是内部的,那么没关系除非两个定义都出现在同一个文件中

如果没有联动,则没有问题。

除非我忽略了什么,thread_local 对链接没有影响,所以通常的规则适用(并且在一个翻译单元而不是另一个翻译单元中定义变量 thread_local 违反了单一定义规则)。

但是,我认为这里的标准存在错误。这 标准(§7.1.1/1)说“如果 thread_local 出现在任何 变量的声明它应该存在于所有 该实体的声明。”没有明确的声明 不需要诊断,或违反此 规则是未定义的行为,因此需要编译器 诊断错误。除了,当然,如果你定义在 命名空间范围:

thread_local int i;

在一个翻译单元中,并且:

int i;

在另一种情况下,编译器可能无法诊断错误 (而且我相当确定委员会不想要求它)。 我的猜测是这里的意图是未定义的行为。

【讨论】:

  • 是的,变量是外部的,所以很遗憾我的想法行不通。那我会尝试其他方法。
【解决方案2】:

根据您的描述,它们听起来像是两个不同的变量(没有一个会影响另一个),在这种情况下,从技术角度来看,这似乎完全可以。

也就是说我永远不会建议这样做,因为最有可能发生的事情是有人会在以后的维护中对其含义感到困惑,并且会在尝试理解代码时造成更多问题。

【讨论】:

  • 它们是否是两个不同的变量取决于名称的链接(不受thread_local的影响)。
【解决方案3】:

这应该可以工作,并产生正确的行为,因为变量是两个不同的变量。

我强烈建议不要这样做,因为它只会降低软件的可维护性。这种行为是否正确似乎不太重要,因为代码的可理解性 - 对行为截然不同的两组数据使用相同的变量名似乎有问题。

【讨论】:

  • @Yakk 作者使用“OK”(我把它放在引号中)来指代问题:“这种情况是否可能并产生定义的行为?”
  • 我同意“这是可能的并且会产生定义的行为”。 :) 但我强烈建议避免将全局(和线程局部)变量命名为与局部变量相同的名称——我建议选择一个命名方案。或者甚至只是,按照惯例,将其粘贴到 namespace thread_local 或其他任何内容中。
  • @Yakk 啊,是的,我只是换个名字而已!如果您将其发布为答案,我会接受!
  • 是否是两个不同的变量取决于链接。如果链接是外部的,则它们是相同的变量。 (我会支持 @Yakk 将它们放在不同的命名空间中的建议。虽然名称 thread_local 不适用于命名空间名称。)
  • @JamesKanze Laugh,这是真的。 :) 那么,namespace virtual 之类的东西怎么样?
猜你喜欢
  • 2014-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
相关资源
最近更新 更多