返回 std::string 的函数在没有 return 语句的情况下崩溃,这与返回 int 而不返回语句的函数不同
function returning std::string crashes without return statement, unlike a function returning int without return statement
#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
对象。
由于这两个函数都有未定义的行为,推测有些徒劳。
相关文章:
- 返回语句后的代码,没有警告
- 三元运算符在返回语句中给出意外的结果
- 返回非 void 的函数中没有返回语句警告
- 如何使用单个返回语句返回对变量的引用
- 当返回语句时,逗号运算符、大括号初始化列表和 std::unique_ptr 组合在一起
- 获取上次执行的返回语句的行
- 返回语句中矢量初始化时出现编译错误
- 快速搜索链表未编译,需要返回语句
- 静态成员函数赋值而不带返回语句
- 在返回语句中构造对象时,std::move() 是否有助于或阻止 RVO?
- 为什么返回语句和打印语句返回不同的答案?
- C++ 非 void 函数的崩溃没有返回语句
- 在返回语句中嵌套条件运算符
- 为什么结构化绑定禁用RVO和移动返回语句
- C - 程序返回值而无需返回语句
- 返回语句中的构造函数语法
- 编译器遇到返回语句时会做什么
- 是一个单一的返回语句清洁器
- C NRVO/复制Elision在括号中带有返回语句
- C 编译器 - 被遗忘的返回语句