为什么 GCC 5.3.0 在将引用绑定到指针时发出警告"this"
Why GCC 5.3.0 gives warning when binding reference to "this" pointer
下面是一个最小的例子:
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)
- OPENCL 警告:不兼容的指针类型将'float __global[16]'传递给类型为 '__global float4 的参数 *
- 我可以在初始化之前使用 std::array 成员变量中的 data() 指针吗?发出警告
- 键入从 DWORD 到 64 位指针的强制转换警告
- 为什么 Clang 警告未使用的指针和未使用的基元,而不是未使用的对象?
- 对列表类中的泛型方法禁用编译器警告 2100,该泛型方法可能包含指针,也可能不包含指针
- 如何警告 C 中 void 指针上的参数不兼容的类型
- 指针警告(并行计算)
- 有什么方法可以为函数指针比较生成警告?
- 为什么GCC在将未初始化的volatile指针强制转换为"void"时发出警告
- C++-带有指针的Weffc++警告
- 警告C4150在尝试包装本机C 类时,指向不完整类型的指针删除
- 不兼容的指针类型警告c
- 了解初始化和声明指针变量时的警告和编译错误
- std::迭代器、指针和 VC++ 警告 C4996
- 对压缩结构成员使用指针时出现编译器警告
- 警告:正在传递第1个参数(共个)..从不带强制转换的整数生成指针
- C++ 构建警告:取消引用类型双关指针将违反严格锯齿规则
- 使用指向函数的指针的外部引用时的链接器警告
- 如何使用未初始化的指针修复C++中的C4700警告
- g++悬空指针警告不一致