News for hackers. Stuff that matters.
Re:Let's write a setjmp by adrian_b on Sunday February 12, 2023 @04:35AM (#34761429)
"setjmp" and "longjmp" are the mechanism for implementing exceptions in C, i.e. they are just another form of writing "catch" and "throw".

The implementation of exceptions, i.e. of jumps over multiple levels of nested functions and blocks, is much simpler in C than in C++, because there are no destructors that must be called when unwinding the stack, so it is enough to restore the CPU registers to the values correct for the program point where the exception must be caught.

This is needed because at the point where the exception is thrown it is not known whether any of the nested functions that must be skipped has modified any of the registers that a function is expected to preserve and where the original values of the registers have been saved.

Any kind of exceptions can be easily misused, which is why it is recommended to be careful with the use of "setjmp" and "longjmp", but they are not more harmful than the use of exceptions in any other language.

The only additional problem of C is that since there are no implicitly called destructors, like in C++ and similar languages, in C the programmer must do what the compiler would do in C++.

This means that if the nested functions that are skipped by a "longjmp" have allocated heap memory, opened files or sockets etc., such resources must be freed in the exception handler marked by a "setjmp".

Therefore the C programmer must keep track of the resources that might have been allocated in the nested functions, e.g. by recording the allocations in some global table.

Re:Let's write a setjmp by ur-whale on Sunday February 12, 2023 @05:13AM (#34761629)
> "setjmp" and "longjmp" are the mechanism for implementing exceptions in C

Correct, but reductive.

They can be used for many other things.

Re:Let's write a setjmp by adrian_b on Sunday February 12, 2023 @05:39AM (#34761775)
The more general POV is that "setjmp" defines a continuation and "longjmp" invokes it.

While the most frequent use of explicit continuations is for implementing exceptions, you are right that there are many other programming techniques based on explicit continuations.

Re:Let's write a setjmp by rwmj on Sunday February 12, 2023 @06:26AM (#34762007)
I'm now wondering if anyone has written an actual continuation library in C (ie saving and restoring the whole stack). Is it possible?
Re:Let's write a setjmp by yvdriess on Sunday February 12, 2023 @06:57AM (#34762173)
yes and yes.
Re:Let's write a setjmp by menaerus on Sunday February 12, 2023 @08:19AM (#34762609)
Coroutines are one good example.
Re:Let's write a setjmp by someweirdperson on Sunday February 12, 2023 @05:35AM (#34761749)
> They can be used for many other things.

The underlying primitive offers even more flexibility, but exceptions (in the sense of programming languages) can also be used for many other things than exceptions (in the sense of natural language, to handle exceptional cases).

Re:Let's write a setjmp by bogomipz on Sunday February 12, 2023 @06:09AM (#34761925)
>"... but exceptions (in the sense of programming languages) can also be used for many other things than exceptions ..."

Can you elaborate? What are the other ways exceptions are used when not used to handle exceptional situations?

Re:Let's write a setjmp by aardvark179 on Sunday February 12, 2023 @06:35AM (#34762045)
As well as being harder to work with correctly setjmp and longjmp are often a lot slower than other exception handling systems as you are paying the full cost of saving lots of register state even if an exception isn’t thrown. I’ve seen this cause serious performance issues on Windows on x86-64 in the past.

It also doesn’t really compose well, so if library A is using it for exceptions and library B is doing something else clever then it’s hard to coordinate those two uses.

Re:Let's write a setjmp by yvdriess on Sunday February 12, 2023 @06:56AM (#34762169)
Can you elaborate? Isn't the c++ exception system built on top of setjmp/longjmp?

For setjmp to have a measurable performance impact, you have to be calling it an awful lot. It is just a handful of mov instructions without dependencies.

Re:Let's write a setjmp by bregma on Sunday February 12, 2023 @07:12AM (#34762259)
None of the popular C++ vendors implement C++ exceptions using setjmp/longjmp on any of the more (and very few of the less) common targets. Maintaining C++ language runtimes is a part of my day job and I am thankful they don't.
Re:Let's write a setjmp by aardvark179 on Sunday February 12, 2023 @08:20AM (#34762617)
Depending on the ABI it’s saving a lot of registers, and it is very easy to end up calling it a lot if you cannot guarantee the code that may be called by functions you call and you need to do any cleanup.

C++ and other languages tend to make the fast path of no exception extremely fast and store additional data about functions that allow for stack unwinding when an exception is thrown.

Re:Let's write a setjmp by jcranmer on Sunday February 12, 2023 @10:11AM (#34763374)
> Isn't the c++ exception system built on top of setjmp/longjmp?

It is not. The dominant C++ exception system is based on "zero-cost exception handling", which refers to the fact that you do not call any extra code (like setjmp) until an exception is to be thrown. All of that logic is instead encapsulated in tables of exception-handling data and sophisticated unwind routines that look up those tables to figure out where to transfer control-flow to.

> For setjmp to have a measurable performance impact, you have to be calling it an awful lot.

If you built the C++ exception system on top of setjmp/longjmp, you would have to call setjmp on every instance that begins a try block. This includes implicit try blocks generated for every object that has a nontrivial destructor (which must be called if you unwind through the block). So yeah, you would be calling it an awful lot...

Re:Let's write a setjmp by yvdriess on Monday February 13, 2023 @03:36AM (#34771391)
Right, I should have known, libunwind is a basic requirement for supporting a C++ runtime on a target.
Re:Let's write a setjmp by account42 on Monday February 13, 2023 @07:22AM (#34772644)
There are C++ exception implementation's based on setjmp/longjmp though, e.g. MinGW's sjlj configuration.