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

xin*_*aiz 14 c++ gcc reference this language-lawyer

这是最小的例子:

class A
{
    A* const& this_ref;
public:
    A() : this_ref(this) {}
};
Run Code Online (Sandbox Code Playgroud)

GCC 5.3.0发出警告:

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

那是this暂时的吗?什么... MSVC 2015对此保持沉默,并且this_ref->member在我的情况下在构造函数之外引用类成员给出了预期的行为(但可能仅仅是UB的情况,不确定).


编辑:

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

Ker*_* SB 18

您正在创建一个悬空参考.您的代码与此代码没有区别:

struct X
{
    const int & r;
    X() : r(5) {}
};     // ^^^^ dangles
Run Code Online (Sandbox Code Playgroud)

没有"对象"被称为this.this是一个关键字,当用作表达式时,它是包含当前实例地址的prvalue(临时).

这是另一个从类似于对象的东西创建类似悬挂引用的示例,但不是:

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

    Y() : r(a) {}
};
Run Code Online (Sandbox Code Playgroud)

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

总的信息是你应该小心使用允许const左值引用绑定到rvalues的语言特性.它的主要目的是使函数调用变得容易,但它的其他用途更加繁琐.


son*_*yao 5

那是this暂时的吗?

确切地说,this这不是暂时的,而是在这里创建一个临时的.

首先,thisprvalue,

以下表达式是prvalue表达式:

其次,绑定对prvalue的引用时将创建临时对象,

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

这就是GCC发出警告的原因,因为this_ref它必然会被临时创建.(然后变得悬空,导致UB.)