在堆栈展开期间,在异常中引用的局部变量会发生什么?考虑以下代码:
class bar;
class my_error
{
public:
my_error(const bar& bar) : _bar(bar) {}
const bar& get_bar() const { return _bar; }
private:
const bar& _bar;
}
...
bar some_local_object(...);
if (!foo()) {
throw my_error(some_local_object);
}
...
try {
g();
} catch (my_error& e) {
e.get_bar()
...
}
some_local_object 发生了什么?它不应该在堆栈展开期间被销毁吗?如示例中所提供的,使用它是否安全?
附加问题
正如已经回答的那样,这段代码会导致未定义的行为。我的第二个问题是:
如果我既不允许传递对本地对象的引用也不应该尝试复制它,因为在极少数情况下它可能会导致 bad_alloc(我猜这就是为什么 gcc 标准库没有有意义的错误消息,即map.at 抛出 what() 返回“map.at”) 的异常,那么传递附加信息的好策略是什么?请注意,即使连接多个字符串,在构建错误消息期间理论上也可能导致 bad_alloc。即:
void do_something(const key& k, ....)
{
...
if (!foo(k)) {
std::ostringstream os;
os << "Key " << k << " not found"; // could throw bad_alloc
throw std::runtime_error(os.str());
}
// another approcach
if (!foo(k)) {
throw key_not_found(k); // also bad, because exception could outlive k
}
}
最佳答案
行为与返回对堆栈上变量的引用时的行为相同:对象在您使用它之前被销毁。也就是说,在异常被捕获时,被引用的对象被销毁,所有对引用的访问都会导致未定义的行为。
标准中的相关条款是15.2 [except.ctor] paragraph 1:
As control passes from the point where an exception is thrown to a handler, destructors are invoked for all automatic objects constructed since the try block was entered. The automatic objects are destroyed in the reverse order of the completion of their construction.
关于c++ - 抛出具有对局部变量的 const 引用的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27337324/