首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++11中不推荐使用的抛出列表

C++11中不推荐使用的抛出列表
EN

Stack Overflow用户
提问于 2012-12-12 22:07:01
回答 3查看 22.4K关注 0票数 48

正如我在cppreference中看到的,经典的“抛出”声明列表现在在C++11中被弃用了。离开这个机制的原因是什么?我应该如何指定哪些异常抛出我的函数?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-12 22:19:03

有关更详细的推理,请参阅:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3051.html

正如上面国家机构评论中所表达的那样,例外规范在实践中没有被证明是有用的。关于C++中的异常规范的问题有很多讨论(例如,参见Sutter02、Boost03),但主要问题是:

  • 运行时检查: C++异常规范是在运行时检查的,而不是在编译时检查的,因此它们不能保证程序员已经处理了所有异常。运行时失败模式(调用std::recovery.
  • Run-time ())不会导致optimizations.
  • Unusable开销:运行时检查要求编译器生成额外的代码,这也会阻碍泛型代码中的异常:在泛型代码中,通常不可能知道模板参数上的操作可能引发哪些类型的异常,因此无法编写精确的异常规范。

在实践中,只有两种形式的异常抛出保证是有用的:操作可能抛出异常(任何异常),或者操作永远不会抛出任何异常。前者是通过完全省略异常规范来表示的,而后者可以表示为throw(),但由于性能方面的考虑,很少会这样做。

N3050引入了一种新的异常规范,noexcept,它指定函数不会抛出任何异常。与throw()不同,noexcept不需要编译器引入代码来检查是否抛出了异常。相反,如果指定为noexcept的函数通过异常退出,则结果是调用std::terminate()。

有了noexcept的引入,程序员现在可以表达在实践中有用的两种异常保证,而不需要额外的开销。因此,本文建议弃用“动态”异常规范,也就是那些写为throw(type-id-listopt)的异常规范。

票数 53
EN

Stack Overflow用户

发布于 2017-03-12 05:59:19

Peter给出的答案并没有触及实现者和用户的异常规范的实际问题:

如果实现者未能保证只通过调用具有异常规范的方法抛出已定义的exceptions.

  • Thus,则
  • 异常规范会导致程序终止(或者更准确地说,调用终止处理程序)。作为库用户,您正在使自己的代码更容易完全失败/终止。如果库函数运行时内存不足(std::bad_alloc),您将没有机会捕获,但您将被终止。
  • 因此,传达最可能的失败选项并要求您作为用户处理这些选项的原始目标没有实现。
  • 作为另一方的实现者,您不能再真正调用没有异常规范的任何其他方法,因为这些方法可能会导致您终止调用者。这是一个可怕的地方。

结论是,C++应该像Java那样做:

  • 如果调用具有异常规范的方法,并且您自己也有异常规范,则必须捕获异常或在自己的异常specification.
  • The编译器中指定该异常。

Noexcept (因为C++11)遭受了相同的概念错误,因为如果不遵守规范,它也会导致运行时终止,例如,一个方法抛出了声明不是的方法。这使得除了最包含的情况(move constructors come to mind)之外,noexcept不可能用于任何严重的情况。

票数 9
EN

Stack Overflow用户

发布于 2012-12-12 22:17:32

它们会产生更慢更大的代码,因为libc++必须检查从函数中传播出来的任何异常是否违反了它的异常规范,并调用std::unexpected。这几乎是没有用的,而且比仅仅记录函数抛出的异常更糟糕。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13841559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档