【问题标题】:How to handle an exception thrown from a function defined as noexcept?如何处理定义为 noexcept 的函数引发的异常?
【发布时间】:2021-06-06 18:41:18
【问题描述】:

据说定义一个函数为noexcept会让编译器做一些优化来提升程序,如果函数需要抛出,编译器会抑制优化。

这是我的简单 sn-p:

void func() noexcept(true){
    std::vector<int> vec{2, 4, 6, 8}; // vec is a vector of 4 ints
    std::cout << vec.at(5); // throws
}

int main(){

    try{
        func();
    }
    catch(std::exception const& e){
        std::cout << e.what() << '\n';
    }
    catch(...){
        //
    }

}
  • 为什么我无法捕获异常?我确定是因为noexcept 异常规范。那么,如果一个函数被标记为noexcept 但抛出了异常,如何捕获它的异常而不是让程序调用std::terminate() 来结束程序呢?

【问题讨论】:

  • func 承诺永远不会抛出异常;如果它违反了承诺,将调用std::terminate。您必须更改func 的主体才能捕获异常并以另一种方式返回错误。
  • 还有这个信息"...如果函数需要抛出编译器会抑制优化..."是不正确的。
  • 并直接回答您的评论 - func 已承诺从不抛出,所以 "...might throw..." 是不可能的并且优化(如果有的话)总会发生。
  • @ItachiUchiwa 不,你只是误解了它的意思。 "此外,如果编译器知道不会抛出异常[因为使用了nothrow(true)],它可以(有时)执行如果代码可能抛出必须抑制的优化[当不使用nothrow(true)时]"
  • 不,您误解了报价。 "... "此外,如果编译器知道不会抛出异常,..." stop here noexcept(true) 已指定,因此编译器知道不会抛出异常并因此进行优化(如果可能的话)可以执行编译器不会查看func中调用的每个函数,并尝试确定哪些可以抛出,哪些不能。func的作者已经向编译器承诺不会留下任何异常@987654335 @.

标签: c++ exception noexcept


【解决方案1】:

为什么我无法捕捉到异常?

因为函数是noexcept。这正是它的意思。声明一个函数noexcept 是一个承诺,不会从函数中抛出任何东西。因此,编译器不需要生成异常处理代码。如果该承诺被破坏,则无法处理异常,唯一合理的方法是终止。

如果一个函数被标记为 noexcept 但抛出异常会发生什么

如果noexcept函数抛出异常,则终止进程。

以及如何捕获它的异常而不是让程序调用 std::terminate() 来结束程序?

无法捕获noexcept 函数抛出的异常。您的选择是:

  • 接受如果发生这种情况,进程将被终止。
  • 不要让noexcept 函数抛出异常,从而避免终止。请注意,扔进去是可以的,只要不扔东西。
  • 不要将抛出的函数声明为noexcept,以便您处理异常。

【讨论】:

  • 但是您可以在该函数内本地吞下该异常(在其主体内处理它而不让它离开该函数)。
  • @ItachiUchiwa 就像我说的:Don't let exceptions be thrown from noexcept functions。只要你不抛出任何东西,在里面抛出异常就可以了。
  • 好的,谢谢
  • 在某些情况下,另一种选择可能是在程序启动附近使用std::set_terminate,以尝试一些最后的日志记录、清理等。在相同的情况下,程序仍然需要终止,但是可以先做一点。
猜你喜欢
  • 1970-01-01
  • 2017-10-29
  • 2016-06-11
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 2020-10-29
  • 2010-09-17
相关资源
最近更新 更多