为什么 GCC 5.3.0 在将引用绑定到指针时发出警告"this"

Why GCC 5.3.0 gives warning when binding reference to "this" pointer

本文关键字:指针 警告 this 绑定 GCC 引用 为什么      更新时间:2023-10-16

下面是一个最小的例子:

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以外的其他编译器)产生的问题。

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

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

不存在名为this的"对象"。this是一个关键字,当用作表达式时,它是一个包含当前实例地址的右值(临时值)。

下面是另一个例子,从看起来像对象但不是对象的东西创建类似的悬空引用:

struct Y
{
    int a[10];
    int* const & r;
    Y() : r(a) {}
};

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

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

this是临时的吗?

确切地说,this不是临时的,但是这里创建了一个临时的。

首先this是右值,

下列表达式是右值表达式:

    其次,在将引用绑定到右值时将创建临时对象,

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

    • 将引用绑定到右值

    这就是为什么GCC给出警告,因为this_ref被绑定到一个临时创建。(然后被悬挂起来,这导致了UB)