为什么这段代码catch块不执行?

Why does this code catch block not execute?

捕获处理程序不是 运行。但是为什么?

如果 thread ttry 块之前启动,则捕获处理程序 运行s.

如果 catch 块的类型与抛出的类型不匹配,程序将退出并解释线程因未捕获的异常而终止,这表明异常已被处理,但 catch 块不是 运行。

#include <iostream>
#include <thread>

using namespace std;

void do_work() {}

int main() {
  std::cerr << "RUNNING" << std::endl;
  try {
    thread t(do_work);
    std::cerr << "THROWING" << std::endl;
    throw logic_error("something went wrong");
  } catch (logic_error e) {
    std::cerr << "GOTCHA" << std::endl;
  }

  return 0;
}

编译命令:

c++ -std=c++14 -pthread -pedantic -Wall -Wextra -O0 scratch.cpp -o scratch

您忘记加入主题了:

try {
  thread t(do_work);
  t.join();                                    // <<< add this
  std::cerr << "THROWING" << std::endl;
  throw logic_error("something went wrong");
} catch (logic_error e) {
  std::cerr << "GOTCHA" << std::endl;
}

在超出范围之前 joinable thread that goes out of scope, causes terminate to be called. So, you need to call either join or detach

C++11, 30.3.1.3, thread destructor标准说

If joinable() then terminate(), otherwise no effects. [Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. —end note]

因此,一旦线程析构函数被调用,您的程序就会 terminates 因为作用域结束并且 catch 逻辑永远不会被执行。

如果您希望您的程序在线程范围之外捕获异常但在线程仍可连接时抛出异常,则需要在线程本身的范围内捕获它,join or detach 线程并重新抛出任何被捕获的东西。

try 
{
  std::thread t(foo);
  try
  {
    std::cerr << "THROWING" << std::endl;
    throw std::logic_error("something went wrong");
  }
  catch (...) // catch everything
  {
    t.join(); // join thread
    throw; // rethrow
  }
  t.join();
}
catch (std::logic_error & e) 
{
  std::cerr << "GOTCHA: " << e.what() << std::endl;
}