This answer claims:
The exception object is destroyed when the last catch block that does not exit via a re-throw (i.e. a parameterless throw expression evaluation) completes.
However, this code prints asdf:
#include <iostream>
#include <thread>
#include <stdexcept>
std::exception& get_err() {
  try {
    throw std::runtime_error("asdf");
  } catch (std::exception& e) {
    return e;
  }
}
int main() {
  std::thread t;
  {
    std::exception& err = get_err();
    t = std::thread([&](){
      std::this_thread::sleep_for(std::chrono::seconds(1));
      // is this not a use-after-free error?
      std::cout << err.what() << "\n";
    });
  }
  t.join();
  return 0;
}
Is this undefined behavior? Why can I use a reference to this exception object long after the "last catch block"?
Is the l-value reference to err extending the lifetime of the object (into the thread's lambda)? What if the lifetime wasn't extended, would this still work?
I am on MSVC 2019 C++20, but would be interested in other compilers/standard as well.
