It's common knowledge that returning a pointer to a stack variable is generally a bad idea:
int* foo() {
int i = 0;
return &i;
}
int main() {
int* p = foo();
}
In the example above, my understanding is that the int is destroyed and so p is a dangling pointer.
I am wondering about the extent to which this applies to the newly introduced coroutines of C++20:
generator<span<byte>> read(stream& s) {
array<byte, 4096> b;
while (s.is_open()) {
const size_t n = s.read_some(b);
co_yield span(b, n);
}
}
int main() {
stream s;
for (span<byte> v : read(s)) {
/* ... */
}
}
In this example, the coroutine read yields a span view into the local buffer b. Internally, that view stores a pointer to the buffer. Will that pointer ever be dangling when v is used with the body of the range-for loop?
For context, the coroutine code in the second example is modeled after the code in my own project. There, AddressSanitizer ends the program with a "use-after-free" error. Ordinarily I'd consider that enough to answer my question, but since coroutine development is still coming along at this point in time (my project is using boost::asio::experimental::coro, emphasis on "experimental"), I was wondering if the error was caused by a bug with generator's implementation or if returning pointers in this way is fundamentally incorrect (similar to the first example).
With language coroutines, this has to be safe: the lifetime of
bmust continue until the generator is finished, so pointers to it must be useful that long.