[英]Reference to the this pointer: GCC vs clang
请考虑以下代码:
struct A {
private:
A* const& this_ref{this};
};
int main() {
A a{};
(void)a;
}
如果使用-Wextra
编译, GCC v6.2和clang v3.9都会显示警告。
无论如何,通过下面显示的略微修改版本,它们的行为有所不同:
struct A {
A* const& this_ref{this};
};
int main() {
A a{};
(void)a;
}
在这种情况下, GCC不会发出任何警告, clang会给出与前一个示例中返回的相同的警告。
警告几乎完全相同。
它遵循clang中的那个:
3:警告:将引用成员'this_ref'绑定到临时值[-Wdangling-field]
哪个编译器是对的?
我会说GCC在这种情况下是错误的,我正在打开一个问题,但也许这是相反的,因为该语言的一个神秘的角落案例。
会员声明
A* const& this_ref{this};
绑定对在构造函数执行期间仅存在的临时的引用(注意: this
是一个rvalue表达式)。
我不确定this
是否在该上下文中正式可用,但是如果它随后使用该指针则会出现严重的UB情况。
回覆
“哪个编译器是对的?
...编译器可以根据需要发出尽可能多的诊断信息。 发布诊断并没有错。 因此根据您的描述,两者都接受代码,然后两个编译器都是正确的(我认为最有可能),或者两者都是错误的。
这个警告的原因是IMO摘录自标准(12.2.5):
绑定到构造函数的ctor-initializer(12.6.2)中的引用成员的临时绑定将持续存在,直到构造函数退出。
由于关键字this是一个prvalue表达式 ,因此在this_ref
初始化期间将创建一个临时表 ,并将this_ref
绑定到该临时表。
但我怀疑你的引用是否实际上是在ctor-initializer
。
如果你写:
struct A {
private:
const int& rr = 1+1;
};
然后你将重现与gcc完全相同的问题,删除私人也将删除此警告。
据我所知, this pointer
可能在非静态成员函数的主体中使用,我从未读过它可以在默认成员初始化期间用作参数。
this
是prvalue ,并且在绑定对prvalue的引用时将创建临时对象 ,因此您将引用成员绑定到临时的默认成员初始值设定项中 。
并且默认成员初始化程序中的临时引用成员绑定到临时成员是不正确的,这是由标准明确声明的。
$ 12.6.2 / 11初始化基数和成员[class.base.init] :
从默认成员初始值设定项绑定到引用成员的临时表达式格式不正确。 [例如:
struct A { A() = default; // OK A(int v) : v(v) { } // OK const int& v = 42; // OK }; A a1; // error: ill-formed binding of temporary to reference A a2(1); // OK, unfortunately
- 结束例子]
参见CWG 1696 ,这适用于C ++ 14。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.