const 引用是否绑定到另一个从临时悬挂引用转换而来的引用?
Is a const reference bound to another reference which is cast from temporary a dangling reference?
下面是代码片段:
#include <iostream>
using namespace std;
struct B{
int b;
~B(){cout <<"destruct B" << endl;}
};
B func(){
B b;
b.b = 1;
return b;
}
int main(){
const B& instance = (const B&)func(); //is `instance` a dangling reference?
cout <<instance.b<<endl;
return 0;
}
在this online compiler中的输出是
destruct B
destruct B
1
所以 return 值似乎比 cout
操作更早销毁。所以 instance
似乎是一个悬空引用。
如果我们把const B& instance = (const B&)func();
改成const B& instance =func();
,那么结果就是
destruct B
1
destruct B
作为补充,如果我在vs2015中测试代码,那么输出的是最后一个。但是如果在 gcc(before 4.6) 中测试,输出的是前者,4.6以后的版本输出的是后者。所以我想知道是在线编译错误还是引用悬空。
根据最新稿[class.temporary]/6(无关部分被我删掉):
The third context is when a reference is bound to a temporary object. The temporary object to which the reference is bound or the temporary object that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference if the glvalue to which the reference is bound was obtained through one of the following:
...
a const_cast ([expr.const.cast]), static_cast ([expr.static.cast]), dynamic_cast ([expr.dynamic.cast]), or reinterpret_cast ([expr.reinterpret.cast]) converting, without a user-defined conversion, a glvalue operand that is one of these expressions to a glvalue that refers to the object designated by the operand, or to its complete object or a subobject thereof,
...
... [ Note: An explicit type conversion ([expr.type.conv], [expr.cast]) is interpreted as a sequence of elementary casts, covered above. [ Example:
const int& x = (const int&)1; // temporary for value 1 has same lifetime as x
— end example ] — end note ]
您的代码格式正确。
在C++14之前,标准中对这种情况的措辞不明确,存在缺陷问题1376. This issue clarifies the lifetime of the temporary object should not be extended in such case. However, this clarification is superseded by issue 1299(C++17中也没有解决,但在当前草案)。
所以可以断定在issue 1299解决之前,是GCC 4.6以后版本的bug。 GCC 还有一个 bug report 52202。
下面是代码片段:
#include <iostream>
using namespace std;
struct B{
int b;
~B(){cout <<"destruct B" << endl;}
};
B func(){
B b;
b.b = 1;
return b;
}
int main(){
const B& instance = (const B&)func(); //is `instance` a dangling reference?
cout <<instance.b<<endl;
return 0;
}
在this online compiler中的输出是
destruct B
destruct B
1
所以 return 值似乎比 cout
操作更早销毁。所以 instance
似乎是一个悬空引用。
如果我们把const B& instance = (const B&)func();
改成const B& instance =func();
,那么结果就是
destruct B
1
destruct B
作为补充,如果我在vs2015中测试代码,那么输出的是最后一个。但是如果在 gcc(before 4.6) 中测试,输出的是前者,4.6以后的版本输出的是后者。所以我想知道是在线编译错误还是引用悬空。
根据最新稿[class.temporary]/6(无关部分被我删掉):
The third context is when a reference is bound to a temporary object. The temporary object to which the reference is bound or the temporary object that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference if the glvalue to which the reference is bound was obtained through one of the following:
...
a const_cast ([expr.const.cast]), static_cast ([expr.static.cast]), dynamic_cast ([expr.dynamic.cast]), or reinterpret_cast ([expr.reinterpret.cast]) converting, without a user-defined conversion, a glvalue operand that is one of these expressions to a glvalue that refers to the object designated by the operand, or to its complete object or a subobject thereof,
...
... [ Note: An explicit type conversion ([expr.type.conv], [expr.cast]) is interpreted as a sequence of elementary casts, covered above. [ Example:
const int& x = (const int&)1; // temporary for value 1 has same lifetime as x
— end example ] — end note ]
您的代码格式正确。
在C++14之前,标准中对这种情况的措辞不明确,存在缺陷问题1376. This issue clarifies the lifetime of the temporary object should not be extended in such case. However, this clarification is superseded by issue 1299(C++17中也没有解决,但在当前草案)。
所以可以断定在issue 1299解决之前,是GCC 4.6以后版本的bug。 GCC 还有一个 bug report 52202。