1

Demo code:

#include <exception>
#include <future>
#include <iostream>
#include <stdexcept>
#include <thread>

void func1() {
  std::cout << "Hello func1\n";
  throw std::runtime_error("func1 error");
}

int main() {
  try {
    std::future<void> result1 = std::async(func1);
    result1.get();
  } catch (const std::exception &e) {
    std::cerr << "Error caught: " <<e.what() << std::endl;
  }
}

Output:

Hello func1
Error caught: func1 error

It seems that the main function can catch exception from thread. But based on this question & answer , the main function should not be able to catch thread exception. It confused me. Maybe I mis-understand some information. Could anyone give some tips? Thanks in advance.

Fareanor
  • 5,900
  • 2
  • 11
  • 37
waltermitty
  • 453
  • 3
  • 12
  • 6
    You are not catching exceptions from `thread`, you are catching them from `async`. These are two different things that work differently. – Daniel Langr Nov 25 '22 at 09:37
  • 3
    `std::future::get`: ["If an exception was stored in the shared state referenced by the future (e.g. via a call to std::promise::set_exception()) then that exception will be thrown."](https://en.cppreference.com/w/cpp/thread/future/get) – 463035818_is_not_an_ai Nov 25 '22 at 09:42
  • And, `std::thread`: [The return value of the top-level function is ignored and if it terminates by throwing an exception, std::terminate is called](https://en.cppreference.com/w/cpp/thread/thread), `std::async`: [if the function f returns a value or throws an exception, it is stored in the shared state accessible through the std::future that async returns to the caller](https://en.cppreference.com/w/cpp/thread/async). – Daniel Langr Nov 25 '22 at 09:44

1 Answers1

3

First things first, std::async and std::thread are not the same thing at all. Moreover, std::async is not required to execute the callable into another thread, it depends on the launch policy you used.
I would suggest you to read the documentation about std::async.

But either way, any thrown exception are already handled by std::async and are stored in the shared state accessible through the returned std::future, which means the exceptions, if any, are rethrowned when you call std::future<T>::get() (which happens in the main thread in your case).

Fareanor
  • 5,900
  • 2
  • 11
  • 37