【问题标题】:How is C++ try/catch different than C setjmp/longjmp? [closed]C++ try/catch 与 C setjmp/longjmp 有何不同? [关闭]
【发布时间】:2013-02-16 20:16:31
【问题描述】:

我知道在C++ 中使用trycatch 块处理异常。我想知道C 中是否有这个功能。所以,现在我知道C 中的基本错误处理是由setjmp/longjmp 完成的。

由于 setjmp/longjmp 中不存在 C++ ,可以假设 try/catch 更好吗?以什么方式???

我可以使用setjmp/longjmpC 中实现try/catch 功能。 那有什么不同??

【问题讨论】:

  • C++ 没有finally 块。
  • C 中的基本错误处理由 setjmp/longjmp 完成 几乎没有人使用 setjmplongjmp。您在“问题”中陈述的大部分内容都是错误的。
  • 大多数 C 错误处理都是通过返回成功/失败值和类似 errno 的变量来完成的。
  • 原来的“x 比 y”标题是有争议的,但问题本身是有效的。投票重新开放。
  • 自行车和香蕉有什么不同?

标签: c++ c error-handling setjmp


【解决方案1】:

我认为主要区别在于 try/catch 知道堆栈上的对象,并且知道如何为堆栈上分配的对象调用 dtors,而 setjmp 对此没有任何作用。

此外,用户界面更加丰富,您可以定义多种异常类型并根据这些类型采取不同的行为

【讨论】:

    【解决方案2】:

    try/catch 将代表RAII。所有离开作用域的对象都将被正确销毁。

    setjmp/longjmp 不会。

    【讨论】:

      【解决方案3】:

      尽管缺少 RAII 等语言功能,setjmp/longjmp 与用于抛出/捕获异常的机制根本不同。如今,使用零成本方法处理异常,当且仅当异常被实际抛出时才会遇到开销,否则没有开销。由于假设是在一个好的应用程序中一般不会抛出异常,因此称为“零成本”。使用 setjmp/longjmp,您将在每次“输入 try 块”时设置跳转点/上下文。因此,仅仅设置跳转点就会有很多运行时开销。过去,异常是使用setjmp/longjmp 实现的(由编译器,使用 RAII 和其他人所说的“缺失”的所有其他东西——所以你可以看到为什么他们的答案不完全正确),所以理论上你可以实现一样,但在性能方面会差很多。更多异常处理实现细节请参考Itanium C++ ABI: Exception Handling

      【讨论】:

      • 我所知道的所有零成本异常处理协议都要求每个线程都有一个静态变量。尽管维护这样一个变量的执行时间成本很小,但它确实在编译器和任何底层任务切换系统(甚至是协作任务切换器)之间引入了一定程度的耦合,在使用基于 setjmp 的方法时可以避免这种耦合。
      【解决方案4】:

      虽然setjmp/longjmp 可能处理也可能不处理析构函数,但从设计的角度来看,这并不是重要的区别。重要的是,当您抛出异常时,您不知道也不关心将在哪里处理它。实现遍历调用堆栈,直到找到可以处理抛出类型的 catch 子句或直到它到达堆栈顶部;在后一种情况下,程序中止。

      【讨论】:

        【解决方案5】:

        我可以使用 setjmp/longjmp 在 C 中实现 try/catch/finally 功能。那有什么不同??

        这就是问题的答案(你不必自己做)。

        【讨论】:

        • 不,不是。能够使用setjmp/longjmp 实现异常机制并不能回答它是如何实际实现的。并且绝对不会尽可能地实现setjmp/longjmp
        • 我没有回答最初的问题,而是回答了他在细节中提出的一个特定问题。在我看来,最重要的答案已经做得很好了。
        猜你喜欢
        • 2020-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-07
        • 1970-01-01
        • 2013-08-08
        相关资源
        最近更新 更多