神螺栓: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;
}
std::coroutine_handle<>::from_address
需要
如果
既不是空指针值也不是addr
的基础地址,则行为未定义。coroutine_handle
在这种情况下,
addr
是this
,它是promise_type
,而不是coroutine_handle
,所以你有未定义的行为。
根据 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