我见过几个类似的代码片段,如下所示:
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;
}
}
在注释之后的行中Is this okay?
,我们读取了在foo
函数中使用分配的 c 样式字符串std::string
。由于字符串因堆栈展开而被破坏,这是未定义的行为吗?
如果它确实是未定义的行为,如果我们main
用这个替换函数呢?
int main() {
foo();
}
由于没有捕获,编译器不会强制展开堆栈,而是what()
在控制台中输出结果并中止程序。那么它仍然是未定义的行为吗?