在C中使用setjmp和longjmp是好的编程实践吗?

z18hc3ub  于 12个月前  发布在  其他
关注(0)|答案(7)|浏览(104)

我是一名C程序员,习惯于具有良好异常处理的OO语言。
据我所知,setjmp和longjmp本质上是一种c风格的传播异常条件的方式,它们看起来也像是一种可以向上传播堆栈的后藤的强化形式。
所以,首先:在这个时间点上,在直接的C中使用这些是好的做法吗?或者它们已经被弃用了?(注意:C不是C
)。
其次,它们在C中有任何用处吗?或者我认为它们是一种遗留机制,被C的异常处理功能所取代?

omhiaaxx

omhiaaxx1#

基本上,你的Assert是正确的,jmp风格的传播本质上与goto是一样的。阅读Dijkstra's (famous and controversial) paper关于goto s的文章,(我认为)它为为什么goto s应该很少使用提供了合理的推理。除非你确切地知道为什么你正在做你正在做的事情(或者您正在从事非常特定的领域--比如嵌入式编程),您不应该接触gotolongjmp

92dk7w1h

92dk7w1h2#

它们被用来实现协程。有几个C++协程库在网上运行,在Unix/Linux中将使用setjmp/longjmp来实现功能。
所以,如果你的目标是实现一个协程库,那么它是否是一个好的实践是一个有争议的问题,因为在这些平台上,它是支持该功能的唯一方法。
如果你的目标是使用一个协程库,你应该搜索其中的一些,甚至有一个名为boost::context的boost vault提议,它已经被批准了。

nkhmeac6

nkhmeac63#

setjmp/longjmp有一些正确的用法。用它们实现协程实际上是不可能的,因为你必须使用(不可移植的)技巧(读:内联汇编)来切换堆栈。
setjmp/longjmp的一个用途是捕捉浮点信号,但这会扰乱C++堆栈的展开,但在C中是正确的。
你也可以实现某种形式的堆栈展开(通过维护你自己的清理处理程序堆栈),并使用它们实现真正的析构函数和C中的异常。这在大型项目中非常方便:缺乏正确的错误处理机制是C的弱点。然而,要正确地做到这一点相当困难,你必须编写一堆宏来完成任务。

m1m5dgzv

m1m5dgzv4#

您应该在异常处理之前提出后藤和longjmp可能不好的问题(Try+catch+finally+..)变得流行起来(使用longjmp)。如果人们不能处理后藤的稀疏使用,使事情变得更容易,那么他们如何处理longjmp异常处理绕过的所有逻辑排列,然后继续像什么都没发生一样?真实的问题是人们在寻找规则而不是概念。

zujrkrfu

zujrkrfu5#

你肯定不想在C++中使用setjmp,正如你所说的那样,这就是异常的作用。你也不想在C中使用它们,因为它非常难以正确。努力寻找其他解决方案。

mbzjlibv

mbzjlibv6#

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

xcitsw88

xcitsw887#

setjmplongjmp是用于绕过正常函数调用和返回流的宏。
setjmp保存longjmp要使用的调用env
正确使用这些宏真的很难,你很容易以未定义的行为结束。
正因为如此,它被强制要求将longjmp限制为1级信号处理程序(实际上最好根本不调用)。
在关键系统中,要求完全不使用。

相关问题