【问题标题】:exception specification vs exception handling异常规范与异常处理
【发布时间】:2013-07-16 17:06:13
【问题描述】:

我们在我们的第 4 个也是最后一个 C++ 课程中,我一直在查看 Herb Sutter 关于异常规范的帖子和一些关于 stackoverflow 的帖子,表明异常规范将在下一个 C++ 版本中被弃用。

我可以找到如何实现异常规范的示例,但我在理解异常规范是什么以及它们与异常处理有何不同时遇到了一些问题。

在提供一些见解方面的任何帮助都将是最有帮助的。

【问题讨论】:

  • 它们在 C++ 的最后一个版本中被弃用(大约两年前)。
  • 异常规范有两种,动态异常规范和noexcept规范,只弃用动态异常规范
  • 它被弃用的原因之一,因为人们无法正确处理它,弊大于利。
  • @JonathanWakely “动态异常规范”表示旧式异常规范;他们没有什么特别“动态”的。
  • @SChepurin 没有人表现出任何伤害;除了具有仍然需要实现的几乎无用功能的固有“危害”。

标签: c++ exception


【解决方案1】:

异常规范要求编译器通过调用std::unexpected()std::set_unexpected() 的替代集来处理所有未列出的异常类型。

它们被普遍认为是一件坏事。

常见的误解:

  • “编译器将检查您是否做了任何可能引发其他异常的事情。”错误的。在编译时不检查 C++ 异常。编译器不会检查您是否抛出其他类型,也不会检查您是否忘记处理未列出的异常类型。
  • “您不能抛出其他类型的异常。” False,在函数内可以抛出任何异常。在运行时,如果函数因任何未列出的异常类型异常终止,则会调用意外处理程序,它有机会将异常替换为列出的类型。

另见std::bad_exception

【讨论】:

  • Ben,这到底是什么意思,为什么@Crazy Eddie 的帖子不正确?
  • @Joe:因为它实际上并没有阻止你抛出其他类型的异常......它只是完全改变了处理方式。
  • 从来没有说过你不能抛出其他类型的异常。
  • ""你不能抛出其他类型的异常。"假,"真。如果“你”是指功能,而不是它的子部分。
  • @curiousguy:该函数仍然可以抛出它喜欢的任何类型的异常。它就是逃不掉。
【解决方案2】:

异常规范指定函数可能抛出的异常。

【讨论】:

  • 不,不是。虽然我理解你为什么会这么想。
  • 更准确地说:异常规范告诉您哪些类型的异常可以从函数中逃脱。
  • 不过,它仍然是一个正确(而且非常简短)的答案。是的,你可以违反这个“合同”,但这并不重要。您也可以破坏其他合同(常量或保护)。这个也只是为此添加了一个显式的运行时处理程序......当你做一些你承诺之外的事情时通常不会发生这种情况。
【解决方案3】:

异常规范,顾名思义,是关于指定函数可能抛出哪些异常;一般来说。但是,可能的执行方式取决于语言。

  • 在 Java 中,编译器静态强制执行此操作,并且如果您的函数可能抛出其他内容(除非其他内容源自特定的基异常类),则编译器将拒绝该程序
  • 在 C++ 中,编译器允许该程序,但它会插入运行时检查,如果抛出任何未指定的内容,它会调用 std::unexpected

一般来说,异常规范几乎受到普遍谴责,因为:

  • 他们编曲不好。如果你调用两个函数分别抛出一组 X 和 Y 异常,那么生成的函数应该至少声明 X 和 Y 的联合。由于它很快变得难以管理,你需要“翻译”将异常转换为某些常见类型,将原始类型包装起来以保留上下文。以 3 或 5 个深度异常链告终并不罕见。
  • 一些基本操作可能会抛出。在 C++ 中,内存分配可能会抛出std::bad_alloc;例如,几乎每一个 STL 集合都容易受到影响。

如果可能,请忘记您曾经了解过异常规范。

【讨论】:

  • "may 是如何执行的" 在 Java 中,空抛出规范保证对调用者没有任何用处。在 C++ 中确实如此; 这就是强制执行。
  • @curiousguy:我不明白你的评论。我具体描述了两种语言的执法工作方式,您的评论似乎与我对两种语言的描述一致。那有什么问题呢?
  • 在 Java 中,许多异常都被豁免了,以至于空抛出规范实际上毫无意义;您编写“一些基本操作可能会抛出”,但在 Java 中,所有这些都是未经检查的异常。不提它会使比较不公平。此外,C++ 中的许多基本构建块都保证不会抛出异常,这使得所描述的比较对于 C++ 来说更加不公平。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多