Gui*_*cot 3 c++ exception stack-unwinding undefined-behavior c++14
我看过几个类似的代码片段,如下所示:
struct MyExcept : std::exception {
explicit MyExcept(const char* m) noexcept : message{m} {}
const char* what() const noexcept override {
return message;
}
const char* message;
};
void foo() {
std::string error;
error += "Some";
error += " Error";
throw MyExcept{error.c_str()};
}
int main() {
try {
foo();
} catch (const MyExcept& e) {
// Is this okay?
std::cout << e.message << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
在注释后面的行中Is this okay?,我们读取了在foo函数中使用分配的c样式字符串std::string.由于字符串是通过堆栈展开来破坏的,这种未定义的行为是什么?
如果它确实是未定义的行为,如果我们main用这个替换函数怎么办?
int main() {
foo();
}
Run Code Online (Sandbox Code Playgroud)
由于没有catch,编译器不会被强制解除堆栈,而是what()在控制台中输出结果并中止程序.那还是未定义的行为吗?
是的,这是未定义的行为.你正在使用一个悬垂的指针.
void foo() {
std::string error;
error += "Some";
error += " Error";
throw MyExcept{error.c_str()};
} // << error goes out of scope here and so does the pointer returned
// from c_str()
Run Code Online (Sandbox Code Playgroud)
由于没有catch,编译器不会被强制解除堆栈,而是
what()在控制台中输出结果并中止程序.那还是未定义的行为吗?
由于默认实现将使用std::terminate并反过来调用,std::abort()这可能仍然是未定义的行为,因为大多数标准处理程序实现将尝试取消引用what().
您可以安装自己的处理程序以避免这种情况.