这似乎是clang ++编译器中的一个错误

时间:2014-02-21 14:06:40

标签: c++ c++11 reference clang++

以下代码正常执行(请参阅here):

#include <iostream>

struct A {
    int i;
    A():i(1){}
    operator int&() { return i; }
};

int& rri = A();

int main()
{
    int& ri = A();
    std::cout << ri << '\n';
    std::cout << rri << '\n';
}

打印

1
1

正如所料。但是,如果我在main()中注释掉前两个语句,只留下

std::cout << rri << '\n';

代码打印0

修改

让我们假设问题出在我的代码上。但后来我问:标准中8.5.3 / 5中第三个要点的目的是什么,我在下面复制了:

  

对类型“cv1 T1”的引用由类型的表达式初始化   “cv2 T2”如下:

     
      
  • 如果引用是左值引用和初始化表达式

         
        
    • 是左值(但不是位字段),“cv1 T1”与“cv2 T2”或

    • 引用兼容   
    • 有一个类类型(即T2是一个类类型),其中T1与T2没有引用相关,可以转换为类型的左值   “cv3 T3”,其中“cv1 T1”与“cv3 T3”引用兼容(通过列举适用的转换函数(13.3.1.6)并选择最佳的转换函数来选择此转换   重载决议(13.3)),

    •   
         

    然后引用绑定到   初始化表达式lvalue在第一种情况下和左值   在第二种情况下转换的结果(或者,在任何一种情况下,转换为   对象的适当基类子对象)。 [注意:通常   lvalue-to-rvalue(4.1),array-to-pointer(4.2)和   函数到指针(4.3)不需要标准转换,和   因此,当对左值的这种直接结合时,它被抑制   完成。 - 尾注]

  •   

1 个答案:

答案 0 :(得分:11)

未定义的行为:rirri都被初始化为引用临时成员,并立即销毁。

悬空引用指向可能被另一个对象重用的某些内存,在这种情况下,您可能会看到该对象的数据。或者您可能会看到其他一些未定义的行为。