C setjmp/longjmp Examples

beginner
24 min

C setjmp/longjmp Examples

Welcome to our comprehensive guide on C's setjmp and longjmp functions! In this lesson, we'll explore these powerful functions that allow you to create complex control structures in your C programs.

By the end of this tutorial, you'll have a deep understanding of how to use these functions, their use cases, and even see some practical examples. Let's dive in! šŸŽÆ

What are setjmp and longjmp?

The setjmp and longjmp functions are part of the C standard library and are used for performing non-local jumps in a program. These functions can be used to create error handling, debugging, and stack manipulation routines.

  • setjmp: Creates a savepoint in the current stack frame where longjmp can later resume execution.
  • longjmp: Resumes execution of the program from a previously created savepoint by setjmp.

šŸ’” Pro Tip: setjmp and longjmp are often used together to create error-handling or control flow mechanisms in C programs.

How do setjmp and longjmp work?

  1. First, the setjmp function creates a savepoint in the current stack frame and returns a value to the calling function.
  2. Then, the longjmp function is called with the savepoint value, and the program resumes execution from the created savepoint.

Let's take a closer look at each function:

setjmp

c
#include <setjmp.h> jmp_buf env; int val; int main() { if (setjmp(env) == 0) { // Regular code execution val = 42; longjmp(env, val); // longjmp to this savepoint } // This code is skipped when longjmp is called printf("This will not be printed.\n"); return 0; }

In the example above, the setjmp function creates a savepoint within the main function. If the returned value is 0, it means that the savepoint was created but not yet resumed (i.e., longjmp has not been called).

longjmp

c
#include <setjmp.h> jmp_buf env; int val; int main() { // Savepoint creation if (setjmp(env) == 0) { val = 42; } // Regular code execution printf("Before longjmp: %d\n", val); // Output: Before longjmp: 0 // Calling longjmp to resume execution from the savepoint longjmp(env, val); // Resume execution from the savepoint created by setjmp // This code will not be executed when longjmp is called printf("This will not be printed.\n"); return 0; }

In the example above, we call longjmp with the savepoint created by setjmp. This causes the program to resume execution from the savepoint, effectively skipping all the code after the setjmp call.

Practical Example: Error Handling with setjmp and longjmp

Let's consider a simple example of a file reader that uses setjmp and longjmp for error handling:

c
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <setjmp.h> jmp_buf env; int read_file(const char *filename) { int fd = open(filename, O_RDONLY); if (fd == -1) { // Savepoint creation if (setjmp(env) != 0) { perror("Error opening the file"); return -1; } } // Regular file reading code ssize_t bytes_read; char buffer[4096]; while ((bytes_read = read(fd, buffer, sizeof(buffer))) > 0) { // Print the read data fwrite(buffer, bytes_read, 1, stdout); } // Close the file close(fd); return 0; } int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "Usage: %s filename\n", argv[0]); return 1; } if (setjmp(env)) { // Error handling code fprintf(stderr, "Error: %s\n", strerror(errno)); return 1; } // Read the file if (read_file(argv[1]) != 0) { // Error handling code fprintf(stderr, "Error reading the file.\n"); return 1; } return 0; }

In this example, the read_file function uses setjmp and longjmp to handle errors during file opening and reading. When an error occurs, the function saves the current execution state using setjmp and then jumps to the error handling code.

Quiz

Quick Quiz
Question 1 of 1

Which function creates a savepoint in the current stack frame?

By now, you should have a good understanding of setjmp and longjmp in C programming. These functions offer a powerful way to create complex control structures, error handling, and stack manipulation routines. With practice, you'll be able to apply these functions in your own projects to make your code more efficient and maintainable.

Happy coding! šŸ“