0

(バージョン 2) を使用して C++ 11 ライブラリを記述しており、呼び出し元の実行にboost::context::execution_context例外を伝達したいと考えています。execution_context

クライアントがライブラリ関数に与えるラムダ内で例外を処理したいと考えています。ただし、場合によっては、例外が boost::context によって正しく処理されないという奇妙な問題に遭遇しました。

これは期待どおりに機能し、ブーストのテストのいくつかと非常によく似ています:

TEST(execution_context, works) {
  // Client callable
  auto &&f = [](boost::context::execution_context<void> &&ctx) {
    throw std::runtime_error("help!");
    return std::move(ctx);
  };

  // Library code
  std::exception_ptr exc{};
  boost::context::execution_context<void> source(
      [&exc, &f](boost::context::execution_context<void> &&ctx) {
        try {
          ctx = f(std::move(ctx));
        } catch (boost::context::detail::forced_unwind const &) {
          throw;
        } catch (...) {
          exc = std::current_exception();
        }
        return std::move(ctx);
      });

  try {
    source = source();
    if (exc) {
      std::rethrow_exception(exc);
    }
  } catch (std::runtime_error const &) {
    std::cout << "Runtime Error Caught" << std::endl;
  }
}

出力:

[ RUN      ] execution_context.works
Runtime Error Caught
[       OK ] execution_context.works (0 ms)

ただし、次の変更は機能しません。

以下をラップするクラスを追加しますexecution_context

class Core {
  boost::context::execution_context<void> ctx_;

public:
  explicit Core(boost::context::execution_context<void> &&ctx)
      : ctx_{std::move(ctx)} {}

  auto &&done() { return std::move(ctx_); }
};

ここで、前と同じテストを行いますが、定義済みのクラスを使用します。

TEST(execution_context, fails) {
  // Client callable
  auto &&f = [](Core c) {
    throw std::runtime_error("help!");
    return c.done();
  };

  // Library code
  std::exception_ptr exc{};
  boost::context::execution_context<void> source(
      [&exc, &f](boost::context::execution_context<void> &&ctx) {
        try {
          ctx = f(Core(std::move(ctx)));
        } catch (boost::context::detail::forced_unwind const &) {
          throw;
        } catch (...) {
          exc = std::current_exception();
        }
        return std::move(ctx);
      });

  try {
    source = source();
    if (exc) {
      std::rethrow_exception(exc);
    }
  } catch (std::runtime_error const &) {
    std::cout << "Runtime Error Caught" << std::endl;
  }
}

出力:

[ RUN      ] execution_context.fails
unknown file: Failure
Unknown C++ exception thrown in the test body.
generators.t.tsk: /home/plewis/dpkg/refroot/amd64/opt/include/boost/context/detail/exception.hpp:37: boost::context::detail::forced_unwind::~forced_unwind(): Assertion `caught' failed.
zsh: abort (core dumped)  ./test.t.tsk

私が気付いた唯一の違いは、execution_contextがクラスに含まれているため、例外が不適切に処理されることです。それは意味がありません。

環境

私はGTestを使用しています。

コンパイラ

> g++ --version
g++ (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6)
...

システム

> uname -a
Linux myhostname 2.6.32-642.6.2.el6.x86_64 #1 SMP Mon Oct 24 10:22:33 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux

ブースト

boost version 1.69.0 compiled for amd64

4

1 に答える 1