std::rethrow_exception(3)

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

πŸ’œ std::rethrow_exception β€” the std::rethrow_exception glow-up (from the C++ Standard Library, bestie)

okay so picture this: you caught an exception ages ago, stuffed it into a little ✨keepsake box✨, and now you want it BACK. that's this function. it's std::rethrow_exception from the C++ Standard Library, and honestly? it ate. πŸ“


✨ SYNOPSIS ✨

Defined in header <exception>
[[noreturn]] void rethrow_exception( std::exception_ptr p );  (since C++11)

so it takes an exception pointer p and it throws the previously captured exception object that p refers to β€” or a copy of that object. no cap. and bestie, see that [[noreturn]]? that's not a vibe suggestion, that's the whole point: this function does not come back to you. 😭

πŸ™ˆ important tea: it is unspecified whether a copy is made. and if a copy is made, the storage for it is allocated in an unspecified way. so don't go asking where it lives, because nobody's telling.
πŸ’€ and the big one: the behavior is undefined if p is null. like, undefined. not "oops error message" undefined. undefined undefined. guard your if (eptr) checks, bestie, i'm begging.

🌸 PARAMETERS 🌸

  • p β€” a non-null std::exception_ptr. that's it. that's the whole parameter list. slay for minimalism πŸ’…

πŸŽ€ RETURN VALUE πŸŽ€

(none) β€” because it throws, babes. it never gets to the "return" part. [[noreturn]] said what it said. ✨


🌈 EXCEPTIONS 🌈

okay so there are three possible outcomes and they're all listed, so let's go:

  • the exception object referred-to by p, if no copy is made. 🫢
  • otherwise, a copy of such exception object, if the implementation successfully copied the exception object. πŸ¦‹
  • otherwise, std::bad_alloc or the exception thrown when copying the exception object β€” if allocation fails, or if copying fails, respectively. πŸ’€ (yes, you can get an exception while throwing an exception. it's giving chaos.)

⭐ NOTES ⭐

before P1675R2, rethrow_exception was not allowed to copy the exception object β€” which is literally unimplementable on some platforms, bestie, because on those platforms exception objects are allocated on the stack. 😭 so the rules had to change. history!


🧚 EXAMPLE 🧚

go ahead, run this code πŸ‘‘

#include <exception>
#include <iostream>
#include <stdexcept>
#include <string>

void handle_eptr(std::exception_ptr eptr) // passing by value is ok
{
    try
    {
        if (eptr)
            std::rethrow_exception(eptr);
    }
    catch(const std::exception& e)
    {
        std::cout << "Caught exception: '" << e.what() << "'\n";
    }
}

int main()
{
    std::exception_ptr eptr;

    try
    {
        std::string().at(1); // this generates a std::out_of_range
    }
    catch(...)
    {
        eptr = std::current_exception(); // capture
    }

    handle_eptr(eptr);

} // destructor for std::out_of_range called here, when the eptr is destructed

🌸 POSSIBLE OUTPUT 🌸

Caught exception: 'basic_string::at: __n (which is 1) >= this->size() (which is 0)'

πŸ‘‘ SEE ALSO πŸ‘‘

  • exception_ptr β€” shared pointer type for handling exception objects (C++11) (typedef)
  • current_exception β€” captures the current exception in a std::exception_ptr (C++11) (function)

that's the whole page, bestie, you understood it perfectly, i'm obsessed 🫢✨

xoxo, sourced from http://cppreference.com, version 2024.06.10, and yes the footer really does say std::rethrow_exception(3) β€” go off, documentation πŸ’…πŸ’–

πŸ“¦ where this page comes from