c++协程,done()函数在同一个循环中返回不同的值

问题描述 投票:0回答:2

神螺栓:https://godbolt.org/z/6avWcGqKv

以下代码使用 g++ 12、13、14 编译并运行,均给出相同(错误?)的输出。

clang 18、19 都可以(全部“完成:1”)。

是我的编程错误,还是编译器错误,还是某些UB,还是什么?

Program returned: 0
done: 1
done: 1
done: 1
done: 1
done: 1
done: 0  <-- ???
done: 1
done: 1
done: 1
done: 1

代码:

#include <coroutine>
#include <iostream>
#include <vector>

struct Task {
  struct promise_type {
    Task get_return_object() {
      return {.h = std::coroutine_handle<>::from_address(this)};
    }
    std::suspend_never initial_suspend() noexcept { return {}; }
    std::suspend_always final_suspend() noexcept { return {}; }
    void unhandled_exception() {}
    void return_void() {}
  };
  std::coroutine_handle<> h;
};

Task coro() { co_return; }

int main() {
  std::vector<Task> v;
  for (int i = 0; i < 10; ++i)
    v.push_back(coro());
  for (auto &t : v)
    std::cout << "done: "<< t.h.done() << "\n";

  return 0;
}
c++ gcc g++ coroutine
2个回答
0
投票

您的程序有未定义的行为。

std::coroutine_handle<>::from_address
需要

如果

addr
既不是空指针值也不是
coroutine_handle
的基础地址,则行为未定义。

在这种情况下,

addr
this
,它是
promise_type
,而不是
coroutine_handle
,所以你有未定义的行为。


0
投票

根据 cppreference

std::coroutine_handle<Promise>::from_address
只能传递另一个(兼容)句柄
std::coroutine_handle<Promise>::address
的结果,但您传递的是
promise_type
的地址。要从中重建句柄,您需要
std::coroutine_handle<Promise>::from_promise

Task get_return_object() {
      return { std::coroutine_handle<promise_type>::from_promise(*this)};
    }

返回所有带有 gcc 的 https://godbolt.org/z/9E8aMdK1v

用 clang

-fsanitize=memory
编译的原始代码抱怨:

==1==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x55555561f462 in std::ostream::operator<<(bool) /opt/compiler-explorer/gcc-14.2.0/lib/gcc/x86_64-linux-gnu/14.2.0/../../../../include/c++/14.2.0/ostream:183:16
    #1 0x55555561f462 in main /app/example.cpp:25:26
    #2 0x7ffff7829d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)
    #3 0x7ffff7829e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)
    #4 0x555555586324 in _start (/app/output.s+0x32324)

SUMMARY: MemorySanitizer: use-of-uninitialized-value /app/example.cpp:25:26 in main
Exiting
© www.soinside.com 2019 - 2024. All rights reserved.