noexcept和可靠性保证

时间:2014-02-17 13:45:10

标签: c++ language-lawyer noexcept

最近,我试图在noexcept异常规范上回答我认为的simple question。最终结果是我发现我对noexcept的基本理解是错误的。

在阅读the current draft standard以纠正我的误解时,我发现自己问了一些关于noexcept没有回答的问题here

  1. noexcept是否应被视为安全保证,被调用的函数不仅不会抛出而且不会破坏状态?
  2. 假设(1.)为false:使用noexcept作为可移植的FailFast来终止应用程序而不进行清理以防止已保存状态的损坏是否正确?
  3. 澄清到(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;
    }
    

    Working example of noexcept

2 个答案:

答案 0 :(得分:2)

  1. 是。一个函数不应该破坏状态,周期,是否抛出。它可能想要抛出异常这一事实并不重要。 [当然,不能保证它不会使程序崩溃。但是,应该记录这种行为。 ; - )]
  2. 亩。如果函数期望抛出noexcept,则函数不应该打扰;它应该只调用std::terminate(或std::abort)。

答案 1 :(得分:1)

noexcept是合同保证,非常像assert 这是无法关闭的。如果标记为noexcept的函数 试图通过例外退出,后期条件已经 违反了,你不能指望任何事情;该计划将是 终止。因此,1是错误的。

关于2,它更难。实施可能 展开堆栈直到它尝试离开该功能 noexcept;它可能不是100%明确(至少对我而言) 不要进一步展开堆栈。如果我想终止 应用程序没有清理,然后我会调用abort(),这是 保证立即退出而不采取任何进一步行动。它 也告诉读者到底发生了什么,而不是 依靠不同特征的一些次要影响。

相关问题