【问题标题】:Non-overloadable non-inline function definitions in different translation units不同翻译单元中不可重载的非内联函数定义
【发布时间】:2020-02-25 20:11:22
【问题描述】:

假设我有 2 个 TU,其中 2 个具有外部链接的非内联函数定义,它们仅在返回类型上有所不同。
我的程序违反了哪一段?
[basic.def.odr]/4 说:

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

但是

  1. 这一段说“那是 odr-used” 这可能是也可能不是。
  2. 毕竟,我如何判断我是否在不同的 TU 中定义了相同的非内联函数? [over.dcl]/1 说的是同一个范围。

【问题讨论】:

    标签: c++ c++17 language-lawyer one-definition-rule


    【解决方案1】:

    相信你在找:[basic.link]/9:

    如果两个名称相同([basic.pre])并且在不同的范围内声明,则应表示相同的变量、函数、类型、模板或命名空间

    • 两个名称都具有外部或模块链接,并在附加到同一模块的声明中声明,或者两个名称都具有内部链接并在同一翻译单元中声明;和
    • 两个名称都指同一命名空间的成员或同一类的成员,而不是通过继承;和
    • 当两个名称都表示函数或函数模板时,签名([defns.signature]、[defns.signature.templ])是相同的。

    如果多个具有外部链接的同名声明将声明相同的实体,但它们附加到不同的模块,则程序格式错误;不需要诊断。 [注意:using-declarations、typedef 声明和 alias-declarations 不声明实体,而只是引入同义词。同样,使用指令不声明实体。 ——尾注]

    还有[basic.link]/11

    在所有类型调整之后(在此期间 typedef 被其定义替换),引用给定变量或函数的所有声明指定的类型应相同,但数组对象的声明可以指定不同的数组类型是否存在主要数组绑定 ([dcl.array])。在类型标识上违反此规则不需要诊断。

    还有[defns.signature]:

    ⟨function⟩名称、参数类型列表([dcl.fct])和封闭命名空间(如果有)

    返回类型不是签名的一部分,因此您违反了相同签名意味着相同实体的规则。


    一般来说,在 Davis “我们不配的英雄” Herring 的作品通过之前,标准中关于范围和名称查找的所有讨论都非常失败。

    【讨论】:

      猜你喜欢
      • 2019-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多