参考这个指针: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会给出与上例中返回的警告相同的警告。

警告几乎是相同的。
它来自铿锵之一:

3:警告:将参考成员'this_ref'绑定到临时值[-Wdangling-field]

哪个编译器是正确的?

我会说海湾合作委员会在这种情况下是错误的,我正在开一个问题,但也许是相反的,因为这个语言的一个神秘的角落案例。


此警告的原因是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可能在非静态成员函数的主体中使用,我从来没有读过它可以用作默认成员初始化期间的参数。


成员声明

A* const& this_ref{this};

将引用绑定到仅在构造函数执行期间存在的临时对象(注意: this是一个右值表达式)。

我不确定this情况下是否可以正式使用,但如果使用那个指针,那么你有严重的UB情况。

回覆

哪个编译器是对的?

......编译器可以根据需要发出尽可能多的诊断信息。 发布诊断程序并没有错。 因此,根据你的描述,两者都接受代码,那么这两种编译器都是正确的(我认为这很可能),或者两者都是错误的。


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。

链接地址: http://www.djcxy.com/p/93195.html

上一篇: Reference to the this pointer: GCC vs clang

下一篇: Coffee Script not fire on page change, but works on page load. [Rails 5]