返回 std::string 的函数在没有 return 语句的情况下崩溃,这与返回 int 而不返回语句的函数不同

function returning std::string crashes without return statement, unlike a function returning int without return statement

本文关键字:返回 语句 函数 int return string std 情况下 崩溃      更新时间:2023-10-16
#include <iostream>
#include <string>
using namespace std;
string
crash()
{
}
int
noCrash()
{
}
int
main()
{
    crash(); // crashes
    // noCrash(); // doesn't crash
    return 0;
}

函数 crash() 在 Mingw g++ 4.6.2 中崩溃,函数 noCrash() 执行没有问题。为什么返回字符串的函数在没有 return 语句的情况下崩溃?

两者都是未定义的行为,即使noCrash也可能崩溃。

从标准 6.6.3/2

不带表达式的 return 语句只能在函数中使用 不返回值,即返回类型的函数 void、构造函数 (12.1) 或析构函数 (12.4)。返回语句 具有非 void 类型的表达式只能在函数中使用 返回一个值;表达式的值将返回到 函数的调用方。表达式隐式转换为 返回它所在的函数的类型。返回语句 可能涉及临时对象的构造和复制 (12.2)。 从函数末尾流出等效于没有的返回 价值;这会导致值返回中出现未定义的行为 函数

其中很多是不确定的,但它可以说有助于理解这种观察的实际原因 - 它可以帮助故障排除,甚至性能和空间设计。

因此,在实际意义上,如果函数未能返回一个值,它基本上无法设置寄存器或内存,调用者期望该值;它似乎返回了过去存在的任何垃圾。 如果返回类型为 int,则您刚刚获得一个垃圾值,但对于字符串,您有一个垃圾值,该值旨在(直接或间接)指向字符串用于存储文本值以及可能的一些引用计数器或其他管理数据的堆内存。 稍后在程序中,调用代码将尝试通过删除指针来释放该堆内存。 删除带有垃圾值的指针很可能会使程序崩溃。

可能是因为当您调用crash时,编译器会尝试销毁从未创建的临时std::string对象。

由于这两个函数都有未定义的行为,推测有些徒劳。