C++返回一个std::string &

9
std::string &func(int vlu)
{
    std::string str;
    str = std::to_string(vlu) + "something";

    return str;
}

上面的函数显然是不安全的。
以下是另一个版本。

std::string &func(int vlu)
{
    return std::to_string(vlu) + "something";
}  

我有一些问题:
编译器(gcc)在第二个版本中没有给我任何警告。这样安全吗? 我认为编译器(或其他什么东西?)将创建一个临时变量来保存表达式std::to_string(vlu) + "something"的返回值。所以第二个版本也不安全。我是对的吗?


1
clang和gcc(8.2)会发出警告:prog.cc:5:12: error: non-const lvalue reference to type 'basic_string<...>' cannot bind to a temporary of type 'basic_string<...>' return std::to_string(vlu) + "something"; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. - hellow
4
是的,第二个版本也是不安全的。编译器没有义务警告您关于未定义行为。如果您收到警告,请将其视为您的编译器为您检测到自己的错误的意外惊喜,而不要认为它提供了任何保证。 - Sam Varshavchik
2
可能是C++返回对局部变量的引用的重复问题。 - Lanting
@user463035818 - 实际上函数有可能会“做正确的事情”。这些函数在语法上都是正确的,如果调用者使用返回的引用,则行为未定义。然而,未定义的行为仅意味着标准不限制可能发生的结果,而不意味着“错误”的行为是保证的。最恶劣的未定义行为情况发生在代码看起来正常工作,但在某些后续时间(例如编译器更新、优化设置更改)出现故障的情况下。 - Peter
@Peter 函数本身没有未定义的行为。它只是返回一个无效的引用(始终如此),我会称之为有问题而不是不安全 ;) - 463035818_is_not_a_number
显示剩余9条评论
1个回答

13

不,两个程序都不安全。在这两种情况下,返回的引用都是悬空的,并且使用该引用的行为将是未定义的。

第二个程序也是不良形式的,因为它试图将左值引用(即返回的引用)绑定到一个右值(即临时变量)。由于编译器可能选择不编译第二个程序,因此第二个程序可能被认为是“不那么不安全的”。

要修复函数:当目的是返回新对象时,请勿尝试返回引用。而是返回一个对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接