std::jmp_buf(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… std::jmp_buf β€” bestie edition

okay so first things first: this page lives in the C++ Standard Library manual (section 3, std::jmp_buf(3)), and it's about one very specific little typedef that's lowkey the backbone of old-school error handling. we're gonna get through it together, i promise 🫢


πŸŽ€ NAME

std::jmp_buf β€” literally just std::jmp_buf, that's the whole name, slay


✨ Synopsis

Okay so picture this: it's defined in the header <csetjmp, and it looks like:

typedef /* unspecified */ jmp_buf;

That's it. That's the whole thing. The type is /* unspecified */, which means the standard is being coy on purpose β€” nobody's gonna tell you exactly what it is, and honestly? iconic of them. πŸ™ˆ

The std::jmp_buf type is an array type suitable for storing information to restore a calling environment. Like, it's a little memory box where you stash the vibe of "where we were" so you can teleport back there later. πŸŒ€

And the stored info is sufficient to restore execution at the correct block of the program and invocation of that block. So it knows where to put you back. It's giving GPS for your stack, fr fr.

⚠️ but bestie listen β€” the state of floating-point status flags, or open files, or any other data is NOT stored in an object of type std::jmp_buf. it's just the location info, not your whole life. don't come for me when your file descriptors are still open, i warned you πŸ’€

🌸 Example

okay this one's actually such a cute lil demo β€” a quadratic equation solver that bails out to an error handler when the discriminant goes negative. "Run this code" as the manpage says, and watch the magic ✨

#include <array>
#include <cmath>
#include <csetjmp>
#include <cstdlib>
#include <format>
#include <iostream>

std::jmp_buf solver_error_handler;

std::array<double, 2> solve_quadratic_equation(double a, double b, double c)
{
    const double discriminant = b * b - 4.0 * a * c;
    if (discriminant < 0)
        std::longjmp(solver_error_handler, true); // Go to error handler

    const double delta = std::sqrt(discriminant) / (2.0 * a);
    const double argmin = -b / (2.0 * a);
    return {argmin - delta, argmin + delta};
}

void show_quadratic_equation_solution(double a, double b, double c)
{
    std::cout << std::format("Solving {}xΒ² + {}x + {} = 0...\n", a, b, c);
    auto [x_0, x_1] = solve_quadratic_equation(a, b, c);
    std::cout << std::format("x₁ = {}, xβ‚‚ = {}\n\n", x_0, x_1);
}

int main()
{
    if (setjmp(solver_error_handler))
    {
        // Error handler for solver
        std::cout << "No real solution\n";
        return EXIT_FAILURE;
    }

    for (auto [a, b, c] : {std::array{1, -3, 2}, {2, -3, -2}, {1, 2, 3}})
        show_quadratic_equation_solution(a, b, c);

    return EXIT_SUCCESS;
}

the way setjmp and longjmp are just passing the baton back and forth… main character energy honestly πŸ‘‘


πŸ¦‹ Output

so when you actually run it, you get this:

Solving 1xΒ² + -3x + 2 = 0...
x₁ = 1, xβ‚‚ = 2

Solving 2xΒ² + -3x + -2 = 0...
x₁ = -0.5, xβ‚‚ = 2

Solving 1xΒ² + 2x + 3 = 0...
No real solution

first two slayed, third one hit the longjmp and jumped straight to the error handler. no real solution, no problem, we move πŸ’…


πŸ”₯ See also

  • setjmp β€” saves the context (function macro). the little bookmark you drop in the code 🏷️
  • longjmp β€” jumps to specified location (function). the teleport, the fast travel, the "nvm take me back" πŸš€
  • C documentation for jmp_buf β€” the original recipe, if you wanna see where this all came from πŸ‘‘

and that's the whole page, bestie!! no cap, you now understand std::jmp_buf better than half the people who use it πŸ’–

this lil gem was pulled from http://cppreference.com, dated 2024.06.10, and it's page std::jmp_buf(3) of the manual β€” go forth and jump responsibly, mwah πŸŽ€βœ¨πŸ¦‹

πŸ“¦ where this page comes from