Boost.Coroutineについての補足

昨日のBoost.勉強会でBoost.Coroutineについていくつか質問があったので、補足しておきます。
Hamigaki.Coroutineのコードはすっかり忘れていたので、すぐに答えられなかったのでした。

self.exit()は必要なの?

これはコルーチンの最後の結果を返せるときはreturnで戻ってもOKです。
内部的には

result_type internal_coroutine()
{
    // コルーチンの本体呼び出し
    result_type res = coroutine_body();

    // 最後の結果を返す
    self.yield(res);

    // 最後の次はなし
    self.exit();
}

的なコードになっています。

なお、self_type::exit()には__declspec(noreturn)や__attribute__((noreturn))が付いているので、
対応コンパイラなら「戻り値がない」警告は出ません。

また、Boost.Coroutineを使わない生のコルーチンは元のスレッドと完全に入れ替わっているので、
コルーチン側からreturnすると呼び出し元に戻らずにスレッドが終了してしまいます。
例外を取りこぼしても同じなのでご注意を。
シングルスレッドのプログラムだと即プログラム終了です。

self.exit()が例外を送出する?

self.exit()はexit_exceptionを送出します。これがコルーチンの正常終了です。
呼び出し元へ送出されるのは別の例外coroutine_exitedです。

コルーチンが終了したときにデストラクタは呼ばれるの?

コルーチン内の局所変数に対してはデストラクタが呼ばれます。
ここには細心の注意を払ってコーディングしています。(少なくともHamigaki.Coroutineでは。)
呼び出し元スレッドとコルーチンの切り替えの際には例外処理のコンテキストも切り替えていますし、
コルーチンの終了処理は例外ハンドラのスタックが空になった後に例外を発生させない操作だけで行っています。