简体   繁体   中英

Is it good programming practice to use setjmp and longjmp in C?

I'm a C++ programmer and used to OO languages with good exception handling.

From what I can understand, setjmp and longjmp are essentially a c-style way to propogate exception conditions. They also seem like an intense form of goto that can propogate up the stack.

So, first of all: Is it good practice to use these in straight up C as of this point in time, or are they deprecated? (note: C not C++).

Secondly, do they have any use in C++ or am I correct in thinking they were a legacy mechanism which was replaced by exception handling features of C++?

Essentially, you're right in your assertion that jmp -style propagation is essentially the same thing as goto . Read Dijkstra's (famous and controversial) paper about goto s which (I think) provides sensible reasoning for why goto s should rarely be used. Unless you know exactly why you're doing what you're doing (or you're working in very specific fields -- such as embedded programming), you should not touch either goto or longjmp .

they are used to implement coroutines. There are a couple of c++ coroutine libraries running around on the net, that in Unix/Linux will use setjmp/longjmp to implement the functionality.

So, if your goal is to implement a coroutine library, then it is a moot point if its good practice or not, since on those platforms it is the only way to support that functionality.

if your goal is to use a coroutine library, you should search for some of these instead. There is even a boost vault proposal called boost::context, which is already approved.

There are some correct uses of setjmp/longjmp . Implementing coroutines with them is virtually impossible, since you have to use (nonportable) tricks (read: inline assembly) to switch stacks.

One use of setjmp/longjmp is to catch floating point signals, but this messes up the C++ stack unwinding. Correct in C though.

You can also implement some form of stack unwinding (by maintaining you own cleanup handler stack) and implement true destructors and exceptions in C with them. This is very handy in large projects: the lack of a correct error handling mechanism is the weak point of C. However, it is quite difficult to do it correctly, and you'll have to write a bunch of macros to facilitate the task.

You certainly don't want to use setjmp in C++, as you say that's what exceptions are for. You don't want to use them in C either because it's exceedingly hard to get right. Try very hard to find other solutions.

You should have brought up the issue that goto and maybe longjmp are not good before Exception handling (Try+catch+finally+..) became popular (using longjmp). If people can't handle a sparse usage of goto to make things easier then how can they handle all of the permutations of logic bypassed by the longjmp exception handling and then continue on like nothing happened? The real issue is people are looking for rules instead of concepts.

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

Apart from the answers posted so far, I would like to add that the setjmp in C allow the implementation of tail recursiveness in an elegant way.

So yes, not only it's a good practice but this is the only portable elegant way to do some things in C.

setjmp and longjmp are macros used to bypass normal function call and return flow.
The setjmp saves the calling env to be used by longjmp
Use of these macros correctly is really hard and you can easily end up with undefined behavior.
Because of this, it is mandated for example to restrict longjmp to 1 level of signal handler (best actually to not be called at all).
In critical systems it is required not to be used at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM