godbolt: https://godbolt.org/z/6avWcGqKv
The following code, compiled and run with g++ 12, 13, 14, all give the same (wrong?) output.
clang 18, 19 are fine (all "done: 1").
As far as I understand, since the initial_suspend()
is suspend_never
, after creation, the promise runs immediately to final_suspend
, and should return "true" when querying "done()", but one of them does not.
Is it my programming error, or compiler error, or some UB, or something?
Program returned: 0
done: 1
done: 1
done: 1
done: 1
done: 1
done: 0 <-- ???
done: 1
done: 1
done: 1
done: 1
code:
#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;
}
Per cppreference, std::coroutine_handle<Promise>::from_address
can only be passed the result of another's (compatible) handle std::coroutine_handle<Promise>::address
but you are passing the address of promise_type
. To reconstruct the handle from that, you need std::coroutine_handle<Promise>::from_promise
Task get_return_object() {
return { std::coroutine_handle<promise_type>::from_promise(*this)};
}
returns all ones with gcc https://godbolt.org/z/9E8aMdK1v
The original code compiled with clang and -fsanitize=memory
complained about:
==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