xunzhang
xunzhang

Reputation: 2936

A bug of coroutine of boost1.53?

I use coroutine of boost 1.53 and try the code from http://www.boost.org/doc/libs/1_53_0/libs/coroutine/doc/html/coroutine/coroutine.html#coroutine.coroutine.calling_a_coroutine:

typedef boost::coroutines::coroutine< void() > coro_t;
void fn( coro_t::caller_type & ca, int j) {
  for(int i = 0; i < j; ++i) {
    std::cout << "fn(): local variable i == " << i << std::endl;
    ca();
  }
}

int main(int argc, char *argv[]) {
  // bind parameter '7' to coroutine-fn
  coro_t c( boost::bind( fn, _1, 7) );

  std::cout << "main() starts coroutine c" << std::endl;

  while ( c)
  {
    std::cout << "main() calls coroutine c" << std::endl;
    // execution control is transferred to c
    c();
  }

  std::cout << "Done" << std::endl;

  return EXIT_SUCCESS;
}

output:

fn(): local variable i == 0
main() starts coroutine c
main() calls coroutine c
fn(): local variable i == 1
main() calls coroutine c
fn(): local variable i == 2
main() calls coroutine c
fn(): local variable i == 3
main() calls coroutine c
fn(): local variable i == 4
main() calls coroutine c
fn(): local variable i == 5
main() calls coroutine c
fn(): local variable i == 6
main() calls coroutine c
Done

The output is different from the link in the first two. Is it a Bug?

Upvotes: 1

Views: 144

Answers (1)

Joe Z
Joe Z

Reputation: 17956

Your answer is in the first sentence of the documentation:

The execution control is transferred to coroutine at construction (coroutine-function entered)

When you construct the coroutine, it calls it pretty much immediately, hence the first line gets printed before your message main() starts coroutine c. The coroutine actually starts here:

    coro_t c( boost::bind( fn, _1, 7) );

I would argue that their example output is incorrect as compared to the example itself. In fact, there's no code between the two std::cout calls in main other than while (c), so I don't see how the output could possibly match the example. I don't think testing the continuation predicate is supposed to start the coroutine. Given the example after that first one, I suspect they meant to write:

    std::cout << "main() starts coroutine c" << std::endl;

    // bind parameter '7' to coroutine-fn
    coro_t c( boost::bind( fn, _1, 7) );

You can see in their next example that they call the constructor after the message from main and get the output you'd expect:

int main( int argc, char * argv[])
{
    std::cout << "main(): call coroutine c" << std::endl;
    coro_t c( fn, 7);

    int x = c.get();
    std::cout << "main(): transferred value: " << x << std::endl;

    x = c( 10).get();
    std::cout << "main(): transferred value: " << x << std::endl;

    std::cout << "Done" << std::endl;

    return EXIT_SUCCESS;
}

leads to:

output:
    main(): call coroutine c
    fn(): local variable i == 7
    main(): transferred value: 7
    fn(): local variable i == 10
    main(): transferred value: 10
    Done

Upvotes: 3

Related Questions