【问题标题】:Are uninitialized references zero-initialized and uninitialized scalars default-initialized?未初始化的引用是零初始化的,未初始化的标量是默认初始化的吗?
【发布时间】:2021-11-11 07:41:57
【问题描述】:

下列说法正确吗?

  • 未初始化的引用被视为零初始化。
  • 未初始化的标量被认为是默认初始化的。
  • 任何其他未初始化的实体都不会被视为零初始化或默认初始化。

它们基于[dcl.init.general/6](我的粗体强调):

零初始化T 类型的对象或引用意味着:

  • 如果T是标量类型,则对象初始化为整型文字0(零)转换为T得到的值;
  • 如果T 是(可能是 cv 限定的)非联合类类型,则其填充位和每个非静态数据成员、每个非虚拟基类子对象初始化为零位,并且,如果对象不是基类子对象,每个虚拟基类子对象都是零初始化的;
  • 如果 T 是(可能是 cv 限定的)联合类型,则其填充位初始化为零位,并且对象的第一个非静态命名数据成员初始化为零;
  • 如果T是数组类型,每个元素都初始化为零;
  • 如果T 是引用类型,则不进行初始化

[dcl.init.general/7](我的粗体强调):

默认初始化T 类型的对象意味着:

  • 如果T 是(可能是cv 限定的)类类型([class]),则考虑构造函数。枚举适用的构造函数 ([over.match.ctor]),并通过重载决议 ([over.match]) 为 initializer () 选择最佳构造函数。如此选择的构造函数被调用,并带有一个空参数列表,以初始化对象。
  • 如果T 是数组类型,则每个元素都是默认初始化的。
  • 否则,不执行初始化

【问题讨论】:

  • 出于好奇,您有未初始化引用的示例吗?我认为那是不可能的
  • @Jarod42 无法重新分配参考。
  • 我还有一个问题:是否已经vacuously初始化了一个实体,完全初始化了吗?
  • @eerorika 并非所有默认初始化都是空的。非平凡类类型的默认初始化是非空的,它使用构造函数。 “被默认初始化”有特定的含义,明确定义,即使对于特定类型 T,如果它意味着“对象表示的字节未初始化”,那么它仍然是 默认初始化 .
  • 我假设您的意思是 [dcl.constexpr] p10,不,空洞的初始化在那里是不够的(如示例所示的非规范性)。我认为措辞很差,但应该更准确。

标签: c++ initialization language-lawyer


【解决方案1】:

下列说法正确吗?

不,你是在颠覆他们的逻辑联系。

“零初始化”和“默认初始化”的定义指定了如果标准中的其他内容说“对象是零初始化”的含义。当标准这么说时,您可以使用零初始化的定义来了解它的含义。作为参考,这意味着没有进行初始化。所以零初始化的引用是未初始化的(因此格式错误)。

但这并不意味着相反。未初始化的引用不是零初始化的。这是一个谬论:https://en.wikipedia.org/wiki/Affirming_the_consequent

当标准规定执行零初始化时,引用是零初始化的。

【讨论】:

  • 谢谢。如果我可能再次需要您的专业知识,我已经打开了一个相关的问题here,到目前为止没有得到任何答案。
【解决方案2】:

(同一问题中的几个问题:我会回答一个)

下列说法正确吗?

  • 未初始化的引用被视为零初始化。

没有。没有未初始化的引用之类的东西,因为它需要引用变量或对象,而不是(引用类型)参数或(引用类型)返回类型,其中上下文初始化不适用;根据[dcl.init.ref]/1/3

/1 声明类型为“对 T 的引用”的变量 ([dcl.ref]) 应被初始化。

/3 初始化器可以省略,仅用于参数中的引用 声明([dcl.fct]),在函数返回类型的声明中, 在其类定义中的类成员声明中 ([class.mem]),并且显式使用了 extern 说明符。

关于引用的[dcl.init.general]/6

对 T 类型的对象或引用进行零初始化意味着:

  • [...]
  • [...] 如果 T 是引用类型,则不执行初始化。

它指的是标准的其他部分管理零初始化适用的情况(以及它对不同实体的效果是什么);对于引用的初始化,尤其要考虑静态初始化,按照[basic.start.static]/2 的规定:

[...] 如果不执行常量初始化,具有静态存储持续时间的变量([basic.stc.static])或线程存储持续时间([basic.stc.thread]) 零初始化 ([dcl.init])。零初始化和常量初始化合称为静态初始化; 所有其他初始化都是动态初始化。所有静态初始化都发生在 ([intro.races]) 任何动态初始化之前。

引用类型变量(不是常量初始化)的静态初始化将仅与动态初始化相关,因为静态初始化第一步的零初始化的效果是没有初始化。

【讨论】:

    【解决方案3】:

    未初始化的引用被认为是零初始化的。

    如果未初始化的引用已被零初始化,则可能是这样。也就是说,已零初始化的未初始化引用与尚未零初始化的未初始化引用之间没有可观察到的区别。

    未初始化的标量被认为是默认初始化的。

    可能是未初始化的标量已被默认初始化。也就是说,已默认初始化的未初始化标量和尚未默认初始化的未初始化标量之间没有明显的区别。

    任何其他未初始化的实体都不会被视为零初始化或默认初始化。

    一个实体在被零初始化后被认为是零初始化,在它被默认初始化后被认为是默认初始化。

    【讨论】:

      猜你喜欢
      • 2014-12-29
      • 1970-01-01
      • 2016-02-01
      • 2015-03-22
      • 1970-01-01
      • 2020-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多