【问题标题】:Why GCC 5.3.0 gives warning when binding reference to "this" pointer为什么 GCC 5.3.0 在绑定对“this”指针的引用时会发出警告
【发布时间】:2017-01-19 16:29:23
【问题描述】:

这是最简单的例子:

class A
{
    A* const& this_ref;
public:
    A() : this_ref(this) {}
};

GCC 5.3.0 给出警告:

警告:临时绑定到 'A::this_ref' 只会持续到 构造函数退出 [-Wextra] A() : this_ref(this) {}

那么this 是临时的吗?什么... MSVC 2015 对此保持沉默,在我的情况下,在构造函数之外通过 this_ref->member 引用类成员会产生预期的行为(但可能只是 UB 的情况,不确定)。


编辑:

请注意,此问题将链接的链接扩展为可能的重复项,因为它不是关于创建此类引用的方式的一般问题,而是关于警告 GCC(以及除 MSVC 之外的其他可能的编译器)在创建引用时产生的警告。

【问题讨论】:

  • 由于this 仅在构造函数运行时存在,然后不再存在,因此它是临时的。 (这正是警告告诉你的。)
  • 你能取this的地址吗?不要这么想。如果引用对象没有地址,您希望引用如何工作?
  • @skypjack 我想这两个问题都是由于对 this 指针的误解造成的,但是“可能获得参考……”在阅读 cmets 之前没有任何意义,而且意义不大读完cmets后。此外,这个问题询问特定编译器版本中的特定警告,而链接的问题相当于“我正在尝试用C++11 的特性是因为原因。”
  • @KyleStrand 您应该阅读链接问题的答案。无论如何,我不必说服你任何事情。我投票关闭作为重复,我的两分钱,这是权利和义务,所以......

标签: c++ gcc reference this language-lawyer


【解决方案1】:

您正在创建一个悬空引用。您的代码与此代码没有什么不同:

struct X
{
    const int & r;
    X() : r(5) {}
};     // ^^^^ dangles

没有名为this 的“对象”。 this 是一个关键字,当用作表达式时,它是一个prvalue(一个临时值),包含当前实例的地址。

这是另一个从看起来像对象但不是对象的对象创建类似悬空引用的示例:

struct Y
{
    int a[10];
    int* const & r;

    Y() : r(a) {}
};

这里,a 是一个命名实体(左值),但在r 的初始化器中,表达式 a 是一个纯右值(即数组)。

总的信息是,您应该小心允许 const 左值引用绑定到右值的语言特性。它的主要目的是使函数调用变得容易,但它的其他用途要复杂得多。

【讨论】:

    【解决方案2】:

    那么this 是临时的吗?

    准确地说,this 不是临时的,而是在这里创建了一个临时的。

    首先,thisprvalue

    以下表达式是纯右值表达式:

    其次,temporary object 将在绑定到prvalue时创建,

    在以下情况下会创建临时对象when a prvalue is materialized so that it can be used as a glvalue, which occurs (since C++17)

    这就是 GCC 发出警告的原因,因为 this_ref 绑定到一个临时创建的。 (然后变得悬空,这导致了 UB。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 2021-05-11
      • 2021-12-27
      • 1970-01-01
      • 2018-07-18
      • 1970-01-01
      相关资源
      最近更新 更多