【问题标题】:Why `static` functions in different TUs do not break the ODR?为什么不同 TU 中的“静态”函数不会破坏 ODR?
【发布时间】:2019-05-09 16:39:06
【问题描述】:

ODR 允许我们定义多次相同的内联函数(有一些限制)。

但是,static 函数的简单情况呢?

// First TU
static int foo() { return 0; }
int bar1() { return foo(); }

// Second TU
static int foo() { return 1; }
int bar2() { return foo(); }

如果我们快速阅读 [basic.def.odr]p4,我们可以天真地得出结论,这将是 UB:

每个程序都应包含一个定义,该定义在被丢弃的语句之外的程序中使用的每个非内联函数或变量 (9.4.1);无需诊断。

C++ 标准在哪里指定每个 foo 是不同的函数,因此不会破坏 ODR,即使它们具有相同的名称?

这仅仅是阅读 [basic.link]p2.2 的问题(即,由于内部链接,名称不指代同一实体,因此 [basic.def.odr]p4 不适用于此处)?或者是否有更多的细微差别/规则来做出这个决定(比如 [basic.scope] 中的东西)?

请注意,对于未命名的命名空间,结果很明确,因为名称可能已经不同/唯一。

【问题讨论】:

  • 由于内部链接,名称不指代同一实体,因此此处不适用 odr 完全正确。
  • @Acorn 抱歉,我忽略了language-lawyer 标签。
  • @πάνταῥεῖ 没问题! :) 告诉我们这个错误!链接相关的总是很痛苦......
  • @Acorn 我们预计会有一个特定的行为,但并没有发生,因为 TU 本地函数是在没有 static 说明符的情况下定义的,并且链接器采用了从另一个 TU 找到的第一个定义,即后来被添加到项目中:)。在我们发现后,我什至发布了一个不太受欢迎的quesiton

标签: c++ static language-lawyer linkage one-definition-rule


【解决方案1】:

正确 - 尽管它们在本地具有相同的名称,但它们是两个不同的功能/实体,因此没有违规。

[basic.link]/4.3: 当名称具有内部链接时,它所表示的实体可以被同一翻译单元中其他范围的名称引用。

[basic.link]/5: 具有命名空间范围的名称如果是显式声明的变量、变量模板、函数或函数模板的名称static,则具有内部链接;或 [..]

我无法立即找到任何适用的进一步措辞(规范或其他措辞),但我认为我们不需要。

【讨论】:

  • @Brian 实际上,这看起来像是缺失的部分!
  • Id' 说 [basic.link]/11 是 OP 想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-24
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多