左值引用绑定崩溃为按值返回?

时间:2015-12-15 10:35:14

标签: c++ visual-studio

MSVC正在接受此代码段

#include <iostream>
#include <string>
#include <vector>

std::string retstr() {
 return std::string("HelloWorld");   
}

void callFunc(std::string& ref) {
 std::cout << ref;   
}

int main()
{
    callFunc(retstr());
}

出于某些向后兼容的原因。

现在..我在函数中的DLL中遇到了一些崩溃,其功能与上面的代码片段完全相同:编译器没有警告我将左值引用绑定到按值返回啄。

我的问题是:这可能不是标准的,但它是否会导致程序崩溃(访问违规是准确的)?

2 个答案:

答案 0 :(得分:2)

编写的代码在生命周期中很好,因为临时值retstr()一直存在到完整表达式的结尾,因此只要函数调用它就会存在。

MSVC允许将左值引用绑定到右值的事实不会改变这一点。与往常一样,您必须确保callFunc在函数调用期间之后不会将引用存储到字符串中。

答案 1 :(得分:0)

绑定非常量引用“rvalue”肯定会被编译器标记。但是如果编译器没有标记它(如你的情况那样),那么在运行时会出现问题(也可能会崩溃)。

void callFunc(std::string& ref) {
 std::cout << ref;   //what to display?? if temporary is referenced. 
}

int main()
{
    callFunc(retstr()); //would return temporary which will be lost       immidiately.
}

在你的例子中,临时是引用,遗憾的是它没有被编译器标记。现在,当使用这个引用(ref)时,它可能会崩溃,因为它指向丢失的东西。

我想分享一些可能有用的要点。

  • 如果您只是实施
    • void foo(X&amp;); 如果没有void foo(X&amp;&amp;),行为就像在C ++ 98中一样:可以为左值调用foo(),但不能为rvalues调用。
  • 如果您只是实施
    • void foo(const X&amp;); 如果没有void foo(X&amp;&amp;),行为就像在C ++ 98中一样:可以为左值和右值调用foo()。
  • 如果你实施
    • void foo(X&amp;);
    • void foo(X&amp;&amp;);
    • 或void foo(const X&amp;);
    • void foo(X&amp;&amp;); 你可以区分处理右值和左值。允许rvalues的版本并且应该提供移动语义。因此,它可以窃取传递参数的内部状态和资源。 最后一个仅在c ++ 11中受支持。
相关问题