【问题标题】:Can you bind a reference to an uninitialized member?您可以绑定对未初始化成员的引用吗?
【发布时间】:2012-07-05 06:06:33
【问题描述】:

简短的问题,以下可以吗:

struct X
{
    A& x;
    A  y;
    X() : x(y) {}
};

在结构中颠倒两个成员的顺序肯定没问题,因为它保证y首先被初始化,但这是否有效或调用UB?

此外,以下是否可以:

struct X
{
   X& x;
   X() : x(*this) {}
};

?

【问题讨论】:

  • 问:你尝试的时候发生了什么?
  • @paulsm4:这有什么关系?他问这是否是未定义的行为。即使未定义,该效果仍然可以在特定编译器上“起作用”。
  • 颠倒结构中两个成员的顺序绝对没问题,因为它保证 y 首先被初始化 ...仅当A 不是 POD 时才成立类。

标签: c++ reference


【解决方案1】:

我认为这不会引发未定义的行为。

我认为这种情况与此没有什么不同:

 int *p = new int;

表达式new int 是一个指向未初始化 int 的指针。这里我们用new int 初始化指针 p内容未被读取。

同样,

 int & r = *p; //or *new int

这里我们用*p 初始化reference r内容未被读取

在这两种情况下,内容都不会被读取。 读取未初始化的变量会调用未定义的行为。在这两种情况下,未初始化的是内容,而不是地址,我们没有读取内容。

【讨论】:

  • 对于那些想要关键字的人:取消引用会产生左值。未初始化变量的 UB 来自左值到右值的转换,这是“读取变量”的技术部分。因为我们只得到一个未初始化对象的左值引用,所以没关系。一旦某事导致该转换为右值,就需要初始化某事。
  • @GManNickG:感谢词汇和额外的解释。
【解决方案2】:

引用和变量是不同的东西,每个都有自己的“初始化”。

引用的目的是引用something。唯一的先决条件是something 物理存在。无论其状态是否明确定义,都是另一回事。

引用的初始化不是UB。它可以是 UB 它的使用,在它所指的东西被赋予一个值之前,但这一点也不亚于你在使用初始化变量时得到的东西。

不同的是X() :x(*this) {}

在这里,你给一个函数(x 构造函数)一个指向尚未完全构造的东西的指针。这是“危险的”,因为 - 通常 - 你不知道该函数将对该指针做什么,以及它是否期望它以某种方式“有缺陷”。可能只是“将其存储以备后用”(因此没问题)可能是尊重它以访问...未重构的成员! 这是编译器至少应该警告的事情。

当然,在这种特殊情况下(您只是在初始化一个引用)它不会成为问题,因为“引用构造函数”不会访问被引用的对象。但总的来说不是一个好主意。

【讨论】:

  • 两者相似,即使谈论y*this - 它们都没有完全构造。实际上,您所说的构造是什么意思?初始化了吗?
  • @LuchianGrigore:在这种特殊情况下,这两件事是一致的。但总的来说,他们没有。想象一个有很多成员的结构。当 ctor 或 - 比方说 - 第三个被调用时,第四个没有被构造。通过将 *this 传递给第三个,您可以让第三个的 ctor 使用 *this 访问第四个 memebr。这可以是 UB,因为它可能不希望它未初始化。或者它可以在 4th memebr 的成员中分配一些值……这些值很快就会被 4th ctor 清除。
  • 这在您的情况下被授予永远不会发生的事情(构建引用不会“使用”被引用),但是 *this,在 { 之前必须被视为未定义。
【解决方案3】:

我认为将这个问题分成其他几个点是有意义的:

  1. 这在语法上是否正确,是否只允许一种实现?
  2. 此代码会导致崩溃和高级问题吗?
  3. 编译器是否应该处理第二个问题?

我会回答:是,是,是/否。

我在上面的代码示例中没有看到歧义。语法正确的代码如何破坏内存、崩溃等有数百万种方式。这是另一个例子。

编译器可能会发出警告,因为上面的例子很明显。在具有大量间接、重定义等的真实场景中,编译器可能会感到困惑。我不会过分责备它。算法分析是另一个工具的工作,而不是编译器。

例如下面的代码就完美了:

int *p = NULL;
int &r = *p;

这是 NULL 引用。没什么特别的。

这是我的 2 美分。

【讨论】:

    猜你喜欢
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    相关资源
    最近更新 更多