最近,我试图在noexcept
异常规范上回答我认为的simple question。最终结果是我发现我对noexcept
的基本理解是错误的。
在阅读the current draft standard以纠正我的误解时,我发现自己问了一些关于noexcept
没有回答的问题here。
noexcept
是否应被视为安全保证,被调用的函数不仅不会抛出而且不会破坏状态?noexcept
作为可移植的FailFast来终止应用程序而不进行清理以防止已保存状态的损坏是否正确? 澄清到(2。):目的只是为了防止析构函数从noexcept
进一步调用堆栈,以防止在其中展开。这是基于这样一个假设:这是一个完美的RAII环境,堆栈中的析构函数可以将全局状态清除为持久性,从而破坏它。
未执行展开的示例:
#include <iostream>
#include <exception>
namespace{
struct foo{
void change_state() noexcept
{
// change state and fail
throw std::exception();
}
~foo(){
std::cout << "Destructor called, saved state corrupted!" <<std::endl;
}
};
}
int main(){
::std::set_terminate([](){
std::cout<< "Terminate called" <<std::endl;
});
foo f;
f.change_state();
return 0;
}
答案 0 :(得分:2)
noexcept
,则函数不应该打扰;它应该只调用std::terminate
(或std::abort
)。答案 1 :(得分:1)
noexcept
是合同保证,非常像assert
这是无法关闭的。如果标记为noexcept
的函数
试图通过例外退出,后期条件已经
违反了,你不能指望任何事情;该计划将是
终止。因此,1是错误的。
关于2,它更难。实施可能
展开堆栈直到它尝试离开该功能
noexcept
;它可能不是100%明确(至少对我而言)
不要进一步展开堆栈。如果我想终止
应用程序没有清理,然后我会调用abort()
,这是
保证立即退出而不采取任何进一步行动。它
也告诉读者到底发生了什么,而不是
依靠不同特征的一些次要影响。