在C中使用setjmp和longjmp是否是一种良好的编程习惯?

问题描述 投票:15回答:7

我是一名C ++程序员,习惯了具有良好异常处理能力的OO语言。

据我了解,setjmp和longjmp本质上是一种c样式的传播异常条件的方式。它们似乎还像是goto的强烈形式,可以提升堆栈。

因此,首先:好的做法是在当前时间点在C语言中直接使用它们,还是不建议使用它们? (注意:C不是C ++)。

其次,它们在C ++中有什么用,还是我认为它们是被C ++的异常处理功能所取代的旧机制,我是否正确?

c exception unix
7个回答
7
投票

从本质上讲,您认为jmp样式的传播与goto本质上是一样的。阅读有关Dijkstra's (famous and controversial) papergoto,(我认为)为为什么很少使用goto提供了合理的理由。除非您确切地知道为什么要做自己的工作(或者您在非常特定的领域(例如嵌入式编程)中工作),否则请勿触摸gotolongjmp


5
投票

它们用于实现协程。网上有几个C ++协程库,在Unix / Linux中它们将使用setjmp/longjmp实现该功能。

因此,如果您的目标是实现协程库,那么不管它是否是一个好的实践,这都是有争议的,因为在那些平台上,这是支持该功能的唯一方法

如果您的目标是使用协程库,则应搜索其中一些。甚至还有一个名为boost :: context的Boost Vault提议,该提议已经被批准。


4
投票

setjmp/longjmp有一些正确的用法。用它们实现协程实际上是不可能的,因为您必须使用(非便携式)技巧(请参阅:内联汇编)来切换堆栈。

setjmp/longjmp的一种用法是捕获浮点信号,但这会使C ++堆栈展开变得混乱。不过在C中正确。

您还可以实现某种形式的堆栈展开(通过维护您自己的清理处理程序堆栈),并使用C在它们中实现真正的析构函数和异常。这在大型项目中非常方便:缺少正确的错误处理机制是C的弱点。但是,正确执行它非常困难,并且您必须编写一堆宏才能简化任务。


2
投票
您当然不想在C ++中使用setjmp,因为您说那是例外。您也不想在C中使用它们,因为很难正确实现。尽力寻找其他解决方案。

1
投票
setjmp / longjmp是在纯C中实现自己的异常处理的有用方法。http://sourceware.org/pthreads-win32/announcement.html

0
投票
setjmplongjmp是用于绕过正常函数调用和返回流的宏。setjmp保存要由longjmp使用的呼叫环境正确使用这些宏确实非常困难,并且您很容易以未定义的行为结束。因此,例如,必须将longjmp限制为1级信号处理程序(最好实际上根本不被调用)。在关键系统中,完全不需要使用。

0
投票
您应该在异常处理(Try + catch + finally + ..)流行(使用longjmp)之前提出goto和longjmp不好的问题。如果人们无法处理goto的稀疏用法以使事情变得容易,那么他们如何处理longjmp异常处理绕过的所有逻辑排列,然后继续进行,就像什么都没有发生一样?真正的问题是人们正在寻找规则而不是概念。
© www.soinside.com 2019 - 2024. All rights reserved.