views:

1048

answers:

5

My apologies if this has been address/asked before.

I have to use C for one project and I am thinking of using longjmp/setjmp for error handling as I think it will be much easier to handle error in one central place than return codes. I would appreciate if there is some leads on this.

I am particularly concerned with resource cleanup being correctly done if any such error occurs.

Also how do I handle errors that result in multi-threaded programs using

Even better if there is some c library that already exists for error/exception handling.

+4  A: 

I have only ever found one use for setjmp()/longjmp() and it wasn't to do with error handling.

There really is no need to use it for that since it can always be refactored into something easier to follow. The use of setjmp()/longjmp() is very similar to goto in that it can be easily abused. Anything that makes your code less readable is a bad idea in general. Note that I'm not saying they're inherently bad, just that they can lead to bad code easier than the alternatives.

FWIW, the one place they were invaluable was a project I did in the early days of the industry (MS-DOS 6 time frame). I managed to put together a co-operative multi-threading library using Turbo C which used those functions in a yield() function to switch tasks.

I'm pretty certain I haven't touched them (or had the need to) since those days.

paxdiablo
+1 I've only used them once as well: In a copy-protection for a DOS-game. I used longjmp instead of ordinary branching to confuse the crackers. That somewhat worked because generated code looks like anything but a branch. :-)
Nils Pipenbrinck
Amusing coincidence: I built a cooperative threader ca. 1985 using setjmp()/longjmp() to run on an SGI workstation under their unix flavor of the day. Worked like a charm. Since it was used for animation, it included a rendevous that synchronized all the threads to the vertical interrupt of the video system. I haven't directly used them since then, however.
RBerteig
+3  A: 

Symbian implemented it's Leave mechanism in terms of longjmp() and this serves as a good walk through of all the things you need to do.

Symbian has a global 'cleanup stack' that you push and pop things you want cleaned up should an jump happened. This is the manual alternative to the automatic stack unwinding that a C++ compiler does when a C++ exception is thrown.

Symbian had 'trap harnesses' that it would jump out to; these could be nested.

(Symbian more recently reimplemented it in terms of C++ exceptions, but the interface remains unchanged).

All together, I think that proper C++ exceptions are less prone to coding errors and much faster than rolling your own C equivalent.

(Modern C++ compilers are very good at 'zero overhead' exceptions when they are not thrown, for example; longjmp() has to store the state of all the registers and such even when the jump is not later taken, so can fundamentally never be as fast as exceptions.)

Using C++ as a better C, where you only adopt exceptions and RAII, would be a good route should using longjmp() for exception emulation be tempting to you.

Will
Please, use the correct name: longjmp / setjmp, not 'longjump'.
Adriano Varoli Piazza
thanks for the information. However, the question is specific to using C not C++
MeThinks
@MeThinks, thats fine, my advice is applicable to C; I outlined simulating the stack unwinding (such as Symbian's Cleanup Stack) as how you do the resource cleanup you posed in your question.
Will
A: 

Exceptions are by far a better general mechanism, but in the deep dark days of C past, I wrote a processor emulator that included a command shell. The shell used to setjmp/longjmp for interrupt handling (ie, the processor is running and the user hits break/ctrl-c, the code traps SIGINT and longjmps back to the shell).

plinth
+5  A: 

Have a look at this example/tutorial:
http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html

eaanon01
This link is not working.
Vivek Sharma
+1  A: 

If you are worried about resource cleanup, you have to seriously wonder whether longjmp() and setjmp() are a good idea.

If you design your resource allocation system so that you can in fact clean up accurately, then it is OK - but that design tends to be tricky, and typically incomplete if, in fact, the standard libraries that your code uses themselves allocate resources that must be released. It requires extraordinary care, and because it is not wholly reliable, it is not suitable for long-running systems that might need to survive multiple uses of the setjmp()/longjmp() calls (they'll leak, expand, and eventually cause problems).

Jonathan Leffler