关于异常对象的双重破坏所需的说明

时间:2012-06-19 11:09:27

标签: c++ exception exception-handling

在他富有洞察力的论文中, 的 Error and Exception Handling
@Dave Abrahams 说:

  

如果可能,让你的异常类免受双重破坏。不幸的是,一些流行的编译器偶尔会导致异常对象被销毁两次。如果你可以安排它是无害的(例如通过清零已删除的指针),你的代码将更加健壮。

我无法理解这个特定的指南,有人可以:

  1. 请提供此双重销毁方案&
  2. 的代码示例
  3. 实现自定义异常类以避免这种情况的最佳方法是什么?

3 个答案:

答案 0 :(得分:5)

就像@Tony所说,这个指南意味着防范编译器错误。该指南的历史可以追溯到2001年左右,当时异常支持可能仍然有点不稳定。从那时起,我认为/希望大多数编译器已经修复了这个错误,因此指南可能不再那么相关了。

FWIW,此指南已从the CERT coding practices中删除。在这个页面的讨论中,提出了一个有趣的观点:两次破坏对象是UB,所以无论你在你的课程中如何处理它都永远不会使你的程序完全可预测。

但是,如果您真的希望您的代码可以跨编译器(包括旧版本)移植,那么您应该考虑所有这些小故障。例如,Boost经历了很多工作来解决编译器错误;他们可以简单地编写符合标准的代码并将失败的责任推迟到实现,但这会妨碍他们的库的采用。

在编写代码时是否需要同样谨慎取决于您的要求,并且基本上归结为这个问题:是否支持数十个编译器确实值得进行大量工作?

答案 1 :(得分:3)

引用@chrisaycock的文章:

  “为什么要摧毁两次”?由于编译器错误,这就是原因!这是个   错误,编译器不应该这样做。但他们这样做。我工作过   使用Sun的Studio8编译器我被这个项目所困扰的项目。一世   在catch子句中创建了一个ostringstream对象并发现它   两次毁坏。为了解决这个问题,我在尝试之前将其移至了它,然后它   工作。这种错误不会经常发生。大多数时候   在catch子句中创建对象是好的,但它是必须的   意识到了。

     

此致

     

Andrew Marlow

答案 2 :(得分:1)

标准中没有任何情况可能会导致一个对象被破坏两次。发生这种情况的任何实例都是代表用户的错误,或者,编译器破坏对象(例如异常),然后是编译器错误。我之前从未在任何主要的编译器中听到过这样的错误,并且没有理由相信对于任何编写C ++代码的人来说都会有问题。